]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/5e/seg.c
added 5e (not finished)
[plan9front.git] / sys / src / cmd / 5e / seg.c
1 #include <u.h>
2 #include <libc.h>
3 #include <thread.h>
4 #include "dat.h"
5 #include "fns.h"
6
7 Segment *
8 newseg(u32int start, u32int size, int idx)
9 {
10         Segment *s;
11         
12         s = emallocz(sizeof *s);
13         incref(s);
14         s->start = start;
15         s->size = size;
16         s->ref = emalloc(size + sizeof(Ref));
17         memset(s->ref, 0, sizeof(Ref));
18         incref(s->ref);
19         s->data = s->ref + 1;
20         if(idx == SEGBSS)
21                 s->flags = SEGFLLOCK;
22         P->S[idx] = s;
23         return s;
24 }
25
26 void
27 freesegs(void)
28 {
29         Segment **s;
30         
31         for(s = P->S; s < P->S + SEGNUM; s++) {
32                 if(*s == nil)
33                         continue;
34                 if(decref((*s)->ref) == 0)
35                         free((*s)->ref);
36                 if(decref(*s) == 0)
37                         free(*s);
38                 *s = nil;
39         }
40 }
41
42 void *
43 vaddr(u32int addr, Segment **seg)
44 {
45         Segment **ss, *s;
46
47         for(ss = P->S; ss < P->S + SEGNUM; ss++) {
48                 if(*ss == nil)
49                         continue;
50                 s = *ss;
51                 if(addr >= s->start && addr < s->start + s->size) {
52                         if(s->flags & SEGFLLOCK)
53                                 rlock(&s->rw);
54                         *seg = s;
55                         return (char *)s->data + (addr - s->start);
56                 }
57         }
58         sysfatal("fault %.8ux @ %.8ux", addr, P->R[15]);
59         return nil;
60 }
61
62 void *
63 vaddrnol(u32int addr)
64 {
65         Segment *seg;
66         void *ret;
67         
68         ret = vaddr(addr, &seg);
69         segunlock(seg);
70         return ret;
71 }
72
73 /* might be made a macro for hurr durr performance */
74 void
75 segunlock(Segment *s)
76 {
77         if(s->flags & SEGFLLOCK)
78                 runlock(&s->rw);
79 }
80
81 void *
82 copyifnec(u32int addr, int len, int *copied)
83 {
84         void *targ, *ret;
85         Segment *seg;
86         
87         targ = vaddr(addr, &seg);
88         if((seg->flags & SEGFLLOCK) == 0) {
89                 *copied = 0;
90                 return targ;
91         }
92         if(len < 0)
93                 len = strlen(targ) + 1;
94         ret = emalloc(len);
95         memcpy(ret, targ, len);
96         segunlock(seg);
97         *copied = 1;
98         return ret;
99 }
100
101 void *
102 bufifnec(u32int addr, int len, int *buffered)
103 {
104         void *targ;
105         Segment *seg;
106         
107         targ = vaddr(addr, &seg);
108         if((seg->flags & SEGFLLOCK) == 0) {
109                 *buffered = 0;
110                 return targ;
111         }
112         segunlock(seg);
113         *buffered = 1;
114         return emalloc(len);
115 }
116
117 void
118 copyback(u32int addr, int len, void *data)
119 {
120         void *targ;
121         Segment *seg;
122
123         if(len <= 0)
124                 return;
125         targ = vaddr(addr, &seg);
126         memmove(targ, data, len);
127         segunlock(seg);
128         free(data);
129 }