]> git.lizzy.rs Git - plan9front.git/blob - sys/lib/acid/kernel
devproc: fix mistake
[plan9front.git] / sys / lib / acid / kernel
1 include("/sys/lib/acid/syscall");
2
3 // print various /proc files
4 defn fd() {
5         rc("cat /proc/"+itoa(pid)+"/fd");
6 }
7
8 defn segment() {
9         rc("cat /proc/"+itoa(pid)+"/segment");
10 }
11
12 defn ns() {
13         rc("cat /proc/"+itoa(pid)+"/ns");
14 }
15
16 defn qid(qid) {
17         complex Qid qid;
18         return itoa(qid.path\X)+"."+itoa(qid.vers\X);
19 }
20
21 defn path(p) {
22         complex Path p;
23         if p != 0 then {
24                 return *(p.s\s);
25         } else
26                 return "<null>";
27 }
28
29 // print Image cache contents
30 IHASHSIZE = 64;
31
32 defn imagecacheline(h) {
33         local d, p, q;
34
35         while h != 0 do {
36                 complex Image h;
37
38                 d=(Dev)devtab[h.type];
39                 p = "*closed*";
40                 if h.c != 0 then
41                         p = path(h.c.path);
42                 q = h.qid;
43                 print (h\A, " ref=", h.ref, " pgref=", h.pgref, "\t#", d.dc\r, h.dev\D, " (",
44                         q.path, " ", q.vers\D, " ", q.type\X, ") ", p, "\n");
45                 h = h.hash;
46         }
47 }
48
49 defn imagecache() {
50         local i;
51
52         i=0; loop 1,IHASHSIZE do {
53                 imagecacheline(imagealloc.hash[i]);
54                 i = i+1;
55         }
56 }
57
58 // dump channels
59 defn chan(c) {
60         local d, q;
61
62         c = (Chan)c;
63         d= (Dev)devtab[c.type];
64         q=c.qid;
65         print("chan(", c\A, "): ref=", c.ref\D, " #", d.dc\r, c.dev\D, " (", q.path, " ", q.vers\D, " ", q.type\X, ")");
66         print(" fid=", c.fid\D, " iounit=", c.iounit\D);
67         if c.ref != 0 then {
68                 print(" ", path(c.path), " mchan=", c.mchan\A);
69                 if c.mchan != 0 then {
70                         print(" ", path(c.mchan.path));
71                 }
72         }
73         print("\n");
74 }
75
76 defn chans() {
77         local c;
78
79         c = (Chan)chanalloc.list;
80         while c != 0 do {
81                 if c.ref != 0 then
82                         chan(c);
83                 c=(Chan)c.link;
84         }
85 }
86
87 defn findchan(dev,type,path) {
88         local c;
89
90         c = (Chan)chanalloc.list;
91         while c != 0 do {
92                 if c.ref != 0 then {
93                         if c.dev == dev && c.type == type && c.qid.path == path then
94                                 return c;
95                 }
96                 c=(Chan)c.link;
97         }
98         return 0;
99 }
100
101 defn nchans() {
102         local c, n;
103         
104         n = 0;
105         c = (Chan)chanalloc.list;
106         while c != 0 do {
107                 if c.ref != 0 then
108                         n++;
109                 c = (Chan)c.link;
110         }
111         return n;
112 }
113
114 defn activechanlist() {
115         local l, n;
116         
117         l = {};
118         c = (Chan)chanalloc.list;
119         while c != 0 do {
120                 if c.ref != 0 then
121                         l = append l,c;
122                 c = (Chan)c.link;
123         }
124         return l;
125 }
126
127 defn difflist(a, b) {
128         local l, x;
129         
130         l = {};
131         while a != {} do {
132                 x = head a;
133                 if match(x, b) == -1 then
134                         l = append l, x;
135                 a = tail a;
136         }
137         return l;
138 }
139
140 _active_chan_list = {};
141 defn newchans() {
142         local l, new;
143         
144         l = activechanlist();
145         if _active_chan_list != {} then
146                 newerchans(_active_chan_list);
147         _active_chan_list = l;
148 }
149
150 defn newerchans(oldlist){
151         local new;
152         
153         new = difflist(activechanlist(), oldlist);
154         while new != {} do {
155                 chan(head new);
156                 new = tail new;
157         }
158 }
159
160 // look for channels that refer to themselves
161 defn badchans() {
162         local bad, c, i, len, mtpt, p;
163         
164         c = (Chan)chanalloc.list;
165         while c != 0 do {
166                 if c.ref != 0 then {
167                         bad = "";
168                         p = (Path)c.path;
169                         if p != 0 then {
170                                 path(p);
171                                 mtpt = p.mtpt;
172                                 len = p.mlen;
173                                 i=0; loop 1,len do {
174                                         if mtpt[i] == c then
175                                                 bad = bad+" mtpt self-ref";
176                                         i = i+1;
177                                 }
178                         }
179                         if bad != "" then
180                                 print("chan(", c\A, "):", bad, "\n");
181                 }
182                 c = (Chan)c.link;
183         }
184 }
185
186 NHASH=128;
187 defn mntcache() {
188         local i, m, c;
189
190         i=0; loop 1,NHASH do {
191                 m = cache.hash[i];
192                 while m != 0 do {
193                         complex Mntcache m;
194                         print(m\A, " dev ", m.dev\D, " type ", m.type, " qid (", 
195                                 m.qid.path, " ", m.qid.vers\D, ")\n");
196                         c = findchan(m.dev, m.type, m.qid.path);
197                         if c != 0 then {
198                                 print(" ");
199                                 chan(c);
200                         }
201                         m = m.hash;
202                 }
203                 i = i+1;
204         }
205 }
206
207 // manipulate processes
208 defn proctab(x) {
209         return procalloc.arena+sizeofProc*x;
210 }
211
212 defn proc(p) {
213         complex Proc p;
214         local s, i;
215
216         if p.state != 0 && p.pid != 0 && p.text != 0 then {     // 0 is Dead
217                 s = p.psstate;
218                 if s == 0 then {
219                         s = "kproc";
220                 } else {
221                         s = *(s\s);
222                 }
223                 print(p\A, " ", p.pid, ": ", *(p.text\s), " ", *(p.user\s), " pc ", p.pc, " ", s, " (", *(statename[p.state]\s), ") ut ", p.time[0]\D, " st ", p.time[1]\D, " qpc ", p.qpc, "\n");
224         }
225 }
226
227 defn procenv(p) {
228         complex Proc p;
229         local i, e, v;
230
231         e = p.egrp;
232         complex Egrp e;
233         i=0; loop 1,e.nent do {
234                 v = e.ent[i];
235                 i = i+1;
236                 complex Evalue v;
237                 print(*(v.name\s), "=");
238                 printstringn(v.value, v.len);
239                 print("\n");
240         }
241 }
242
243 KSTACK=4096;
244 if objtype=="amd64" then {
245         KSTACK=16*1024;
246 }
247
248 defn procstksize(p) {
249         complex Proc p;
250         local top, sp;
251
252         if p.state != 0 then {  // 0 is Dead
253                 top = p.kstack+KSTACK;
254                 sp = *p.sched;
255                 print(top-sp\D, "\n");
256         }
257 }
258
259 defn procstk(p) {
260         complex Proc p;
261         local l;
262
263         if p.state != 0 then {  // 0 is Dead
264                 l = p.sched;
265                 if objtype=="386" || objtype=="amd64" then
266                         _stk(gotolabel, *l, linkreg(0), 0);
267                 else
268                         _stk(*(l+4), *l, linkreg(0), 0);
269         }
270 }
271
272 defn procs() {
273         local i;
274
275         i=0; loop 1,conf.nproc do {
276                 proc(proctab(i));
277                 i = i+1;
278         }
279 }
280
281 defn stacks() {
282         local i, p;
283
284         i=0; loop 1,conf.nproc do {
285                 p = (Proc)proctab(i);
286                 if p.state != 0 then {
287                         print("=========================================================\n");
288                         proc(p);
289                         procstk(p);
290                 }
291                 i = i+1;
292         }
293 }
294
295 defn stacksizes() {
296         local i;
297
298         i=0; loop 1,conf.nproc do {
299                 procstksize(proctab(i));
300                 i = i+1;
301         }
302 }
303
304 // segment-related
305 defn procsegs(p) {
306         complex Proc p;
307         local i;
308
309         i=0; loop 1,NSEG do {
310                 psegment(p.seg[i]);
311                 i = i+1;
312         }
313 }
314
315 segtypes = { "text", "data", "bss", "stack", "shared", "physical", "shdata", "map" };
316 defn psegment(s) {
317         complex Segment s;
318
319         if s != 0 then {
320                 print(s\A, " ", segtypes[s.type&SG_TYPE], " ", s.base, "-", s.top, " image ", s.image, "\n");
321         }
322 }
323
324 // find physical address for an address in a given process
325 defn procaddr(p, a) {
326         complex Proc p;
327         local i, s, r;
328
329         r = 0;
330         i=0; loop 1,NSEG do {
331                 s = p.seg[i];
332                 if s != 0 then {
333                         complex Segment s;
334                         if s.base <= a && a < s.top then {
335                                 r = segaddr(s, a);
336                         }
337                 }
338                 i = i+1;
339         }
340         return r;
341 }
342
343 // find an address in a given segment
344 defn segaddr(s, a) {
345         complex Segment s;
346         local pte, pg;
347
348         a = a - s.base;
349         if s.map == 0 || s.mapsize < a/PTEMAPMEM then {
350                 return 0;
351         }
352
353         pte = s.map[a/PTEMAPMEM];
354         if pte == 0 then {
355                 return 0;
356         }
357
358         complex Pte pte;
359         pg = pte.pages[(a%PTEMAPMEM)/BY2PG];
360         if pg == 0 then {
361                 return 0;
362         }
363
364         if pg & 1 then {        // swapped out, return disk address
365                 return pg&~1;
366         }
367
368         complex Page pg;
369         return (KZERO|(pg.pa+(a%BY2PG)))\A;
370 }
371
372 defn kzero() {
373         return main - (main & 0x0FFFFFFF);
374 }
375
376 PTEMAPMEM = (1024*1024);
377 BY2PG = 4096;
378 PTEPERTAB = (PTEMAPMEM/BY2PG);
379 defn up() {
380         if objtype == "386" then {
381                 local mach;
382
383                 MACHADDR = KZERO+0x15000;
384                 mach = MACHADDR;
385                 complex Mach mach;
386                 return mach.externup;
387         }
388         if objtype == "amd64" then {
389                 local proc;
390
391                 proc = *R14;
392                 complex Proc proc;
393                 return proc;
394         }
395         print("up() not implemented for", objtype, "\n");
396         return -1;
397 }
398
399 defn intrcount() {
400         local p, t, i, j;
401
402         p = intrtimes;
403         i=0; loop 1,256 do {
404                 t=0;
405                 j=0; loop 1,20 do {
406                         t = t+*p++;
407                         j=j+1;
408                 }
409                 print(itoa(i, "%5d"), " ", itoa(t, "%11d"), "\n");
410                 i=i+1;
411         }
412 }
413
414 defn needacid(s){
415         print("\trc(\"cd /sys/src/9/", kdir, "; mk ", s, ".acid\")\n");
416         print("\tinclude(\"/sys/src/9/", kdir, "/", s, ".acid\")\n");
417 }
418
419 defn kinit() {
420 if (map()[2]) != {} then {      // map has more than two elements -> active proc
421         kdir = "unknown";
422         KZERO = kzero();
423         
424         if objtype == "386" then {
425                 map({"*data", KZERO, 0xffffffff, KZERO});
426                 kdir="pc";
427         }
428         if objtype == "amd64" then {
429                 map({"*data", KZERO, 0xffffffffffffffff, KZERO});
430                 kdir="pc64";
431         }
432         if (objtype == "mips" || objtype == "mips2") then {
433                 kdir = "ch";
434         }
435         if objtype == "alpha" then {
436                 map({"*data", KZERO, 0xffffffff, KZERO});
437                 kdir = "alpha";
438         }
439         needacid("proc");
440         needacid("chan");
441         needacid("segment");
442         needacid("cache");
443 }
444 }