]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/pc/segdesc.c
fix typo
[plan9front.git] / sys / src / 9 / pc / segdesc.c
1 #include        "u.h"
2 #include        "../port/lib.h"
3 #include        "mem.h"
4 #include        "dat.h"
5 #include        "fns.h"
6 #include        "../port/error.h"
7
8 /*
9  * flags:
10  * P = present
11  * A = accessed (for code/data)
12  * E = expand down (for data)
13  * W = writable (for data)
14  * R = readable (for code)
15  * C = conforming (for code)
16  * G = limit granularity in pages (for code/data)
17  * D = 32 bit operand size (for code)
18  * B = 32 bit stack pointer (for data)
19  * Y = busy (for tss and tss16)
20  * U = available for use by system software
21  */
22
23 static struct {
24         char    *name;
25         char    *flags;
26 } descrtypes[] = {
27         "data",         "--------AWE01--P----U.BG--------",
28         "code",         "--------ARC11--P----U.DG--------",
29         "tss16",        "--------1Y000--P----U..G--------",
30         "ldt",          "--------01000--P----U..G--------",
31         "callg16",      "--------00100--P----U..G--------",
32         "taskg",        "--------10100--P----U..G--------",
33         "intrg16",      "--------01100--P----U..G--------",
34         "trapg16",      "--------11100--P----U..G--------",
35         "tss",          "--------1Y010--P----U..G--------",
36         "callg",        "--------00110--P----U..G--------",
37         "intrg",        "--------01110--P----U..G--------",
38         "trapg",        "--------11110--P----U..G--------",
39 };
40
41 /*
42  * format:
43  * idx[4] type[8] flags[8] dpl[1] base[8] limit[5]\n
44  */
45
46 enum
47 {
48         RECLEN  = 4+1 + 8+1 + 8+1 + 1+1 + 8+1 + 5+1,
49 };
50
51 static long
52 descwrite(Proc *proc, int local, void *v, long n, vlong)
53 {
54         int i, j, t;
55         char buf[RECLEN+1];
56         char c, *p, *s, *e, *f[6];
57         Segdesc d;
58
59         int dpl;
60         ulong base;
61         ulong limit;
62
63         s = (char*)v;
64         e = s + n;
65
66         if(waserror()){
67                 if(proc == up)
68                         flushmmu();
69                 nexterror();
70         }
71
72         while(s < e){
73                 for(p = s; p < e && *p != '\n'; p++);
74                         ;
75                 if((p - s) > RECLEN)
76                         error(Ebadarg);
77                 memmove(buf, s, p - s);
78                 buf[p-s] = 0;
79                 s = p+1;
80
81                 if(getfields(buf, f, nelem(f), 1, " ") != nelem(f))
82                         error(Ebadarg);
83
84                 i = strtoul(f[0], nil, 16);
85
86                 for(t=0; t<nelem(descrtypes); t++)
87                         if(strcmp(descrtypes[t].name, f[1]) == 0)
88                                 break;
89                 if(t == nelem(descrtypes))
90                         error(Ebadarg);
91
92                 dpl = atoi(f[3]);
93                 base = strtoul(f[4], nil, 16);
94                 limit = strtoul(f[5], nil, 16);
95
96                 d.d0 = ((base & 0xFFFF)<<16) | (limit & 0xFFFF);
97                 d.d1 = (base & 0xFF000000) | (limit & 0xF0000) | ((dpl & 3)<<13) | ((base & 0xFF0000)>>16);
98
99                 for(j=0; c = descrtypes[t].flags[j]; j++){
100                         switch(c){
101                         default:
102                                 if(strchr(f[2], c) == nil){
103                         case '0':
104                         case '.':
105                                         d.d1 &= ~(1<<j);
106                                         break;                                  
107                                 } else {
108                         case '1':
109                                         d.d1 |= (1<<j);
110                                         break;
111                                 }
112                         case '-':
113                                 continue;
114                         }
115                 }
116
117                 /* dont allow system segments */
118                 if((d.d1 & SEGP) && ((dpl != 3) || !(d.d1 & (1<<12))))
119                         error(Eperm);
120                 
121                 if(local){
122                         Segdesc *new, *old;
123                         int c;
124
125                         if(i < 0 || i >= 8192)
126                                 error(Ebadarg);
127                         if(i >= (c = ((old = proc->ldt) ? proc->nldt : 0))){
128                                 if((new = malloc(sizeof(Segdesc) * (i+1))) == nil)
129                                         error(Enomem);
130                                 if(c > 0)
131                                         memmove(new, old, sizeof(Segdesc) * c);
132                                 memset(new + c, 0, sizeof(Segdesc) * ((i+1) - c));
133                                 proc->ldt = new;
134                                 proc->nldt = i+1;
135                                 free(old);
136                         }
137                         proc->ldt[i] = d;
138                 } else {
139                         if(i < PROCSEG0 || i >= PROCSEG0 + NPROCSEG)
140                                 error(Ebadarg);
141                         proc->gdt[i - PROCSEG0] = d;
142                 }
143         }
144         poperror();
145
146         if(proc == up)
147                 flushmmu();
148
149         return n;
150 }
151
152 static long
153 descread(Proc *proc, int local, void *v, long n, vlong o)
154 {
155         int i, j, k, t;
156         char *s;
157
158         int dpl;
159         ulong base;
160         ulong limit;
161
162         s = v;
163         for(i = 0;;i++){
164                 Segdesc d;
165
166                 if(local){
167                         if(proc->ldt == nil || i >= proc->nldt)
168                                 break;
169                         d = proc->ldt[i];
170                 } else {
171                         if(i < PROCSEG0)
172                                 i = PROCSEG0;
173                         if(i >= PROCSEG0 + NPROCSEG)
174                                 break;
175                         d = proc->gdt[i - PROCSEG0];
176                 }
177
178                 if(o >= RECLEN){
179                         o -= RECLEN;
180                         continue;
181                 }
182
183                 if(s + RECLEN+1 >= (char*)v  + n)
184                         break;
185
186                 for(t=0; t<nelem(descrtypes); t++){
187                         for(j=0; descrtypes[t].flags[j]; j++){
188                                 if(descrtypes[t].flags[j]=='0' && (d.d1 & (1<<j)) != 0)
189                                         break;
190                                 if(descrtypes[t].flags[j]=='1' && (d.d1 & (1<<j)) == 0)
191                                         break;
192                         }
193                         if(descrtypes[t].flags[j] == 0)
194                                 break;
195                 }
196                 if(t == nelem(descrtypes))
197                         t = 0;
198
199                 s += sprint(s, "%.4lux ", (ulong)i);
200                 s += sprint(s, "%-8s ", descrtypes[t].name);
201
202                 k = 0;
203                 for(j=0; descrtypes[t].flags[j]; j++){
204                         switch(descrtypes[t].flags[j]){
205                         case '-':
206                         case '.':
207                         case '0':
208                         case '1':
209                                 continue;
210                         }
211                         if(d.d1 & (1 << j))
212                                 s[k++] = descrtypes[t].flags[j];
213                 }
214                 if(k == 0)
215                         s[k++] = '-';
216                 while(k < 9)
217                         s[k++] = ' ';
218                 s += k;
219
220                 dpl = (d.d1 & 0x6000)>>13;
221                 base = ((d.d0 & 0xFFFF0000)>>16) | ((d.d1 & 0xFF)<<16) | (d.d1 & 0xFF000000);
222                 limit = (d.d1 & 0xF0000) | (d.d0 & 0xFFFF);
223
224                 s += sprint(s, "%.1d ", dpl);
225                 s += sprint(s, "%.8lux ", base);
226                 s += sprint(s, "%.5lux\n", limit);
227         }
228
229         return s-(char*)v;
230 }
231
232 static long
233 gdtread(Chan*, void *v, long n, vlong o)
234 {
235         return descread(up, 0, v, n, o);
236 }
237
238 static long
239 gdtwrite(Chan*, void *v, long n, vlong o)
240 {
241         return descwrite(up, 0, v, n, o);
242 }
243
244 static long
245 ldtread(Chan*, void *v, long n, vlong o)
246 {
247         return descread(up, 1, v, n, o);
248 }
249
250 static long
251 ldtwrite(Chan*, void *v, long n, vlong o)
252 {
253         return descwrite(up, 1, v, n, o);
254 }
255
256 void
257 segdesclink(void)
258 {
259         addarchfile("gdt", 0666, gdtread, gdtwrite);
260         addarchfile("ldt", 0666, ldtread, ldtwrite);
261 }