1 /* $NetBSD: procs.c,v 1.16 2009/03/18 16:00:23 cegger Exp $ */
2
3 /*
4 * This code is such a kludge that I don't want to put my name on it.
5 * It was a ridiculously fast hack and needs rewriting.
6 * However it does work...
7 */
8
9 #include <sys/cdefs.h>
10 __KERNEL_RCSID(0, "$NetBSD: procs.c,v 1.16 2009/03/18 16:00:23 cegger Exp $");
11
12 #include <stdio.h>
13 #include <strings.h>
14 #include <unistd.h>
15 #include "malloc.h"
16 #include "main.h"
17 #include "debug.h"
18 #include "sets.h"
19 #include "procs.h"
20
21 struct Predicate {
22 int p_index;
23 int p_transno;
24 char *p_str;
25 struct Predicate *p_next;
26 };
27
28 struct Stateent {
29 int s_index;
30 int s_newstate;
31 int s_action;
32 struct Stateent *s_next;
33 };
34
35 struct Object *SameState = (struct Object *)-1;
36 int Index = 0;
37 int Nstates = 0;
38 int Nevents = 0;
39 struct Predicate **Predlist;
40 struct Stateent **Statelist;
41 extern FILE *astringfile;
42
43 int predtable();
44
45 void
46 end_events(void)
47 {
48 int size, part;
49 char *addr;
50
51 IFDEBUG(X)
52 /* finish estring[], start astring[] */
53 if(debug['X'] < 2 )
54 fprintf(astringfile, "};\n\nchar *%s_astring[] = {\n\"NULLACTION\",\n",
55 protocol);
56 ENDDEBUG
57 /* NOSTRICT */
58 Statelist =
59 (struct Stateent **) Malloc((Nstates+1) * sizeof(struct Statent *));
60 /* NOSTRICT */
61 Predlist =
62 (struct Predicate **)
63 Malloc ( (((Nevents)<<Eventshift)+Nstates)*sizeof(struct Predicate *) );
64
65 size = (((Nevents)<<Eventshift)+Nstates)*sizeof(struct Predicate *) ;
66 addr = (char *)Predlist;
67 IFDEBUG(N)
68 fprintf(OUT, "Predlist at %p, sbrk %p bzero size %d at addr %p\n",
69 Predlist, sbrk(0), size, addr);
70 ENDDEBUG
71 #define BZSIZE 8192
72 while(size) {
73 part = size>BZSIZE?BZSIZE:size;
74 IFDEBUG(N)
75 fprintf(OUT, "bzero addr %p part %d size %d\n",addr, part, size);
76 ENDDEBUG
77 memset(addr, 0, part);
78 IFDEBUG(N)
79 fprintf(OUT, "after bzero addr %p part %d size %d\n",addr, part, size);
80 ENDDEBUG
81 addr += part;
82 size -= part;
83
84 }
85 IFDEBUG(N)
86 fprintf(OUT, "endevents..done \n");
87 ENDDEBUG
88 }
89
90 int
91 acttable(FILE *f,char *actstring)
92 {
93 static int Actindex = 0;
94 extern FILE *astringfile;
95 extern int pgoption;
96
97 IFDEBUG(a)
98 fprintf(OUT,"acttable()\n");
99 ENDDEBUG
100 fprintf(f, "case 0x%x: \n", ++Actindex);
101
102 if(pgoption) {
103 fprintf(f, "asm(\" # dummy statement\");\n");
104 fprintf(f, "asm(\"_Xebec_action_%x: \");\n", Actindex );
105 fprintf(f, "asm(\".data\");\n");
106 fprintf(f, "asm(\".globl _Xebec_action_%x# X profiling\");\n",
107 Actindex );
108 fprintf(f, "asm(\".long 0 # X profiling\");\n");
109 fprintf(f, "asm(\".text # X profiling\");\n");
110 fprintf(f, "asm(\"cas r0,r15,r0 # X profiling\");\n");
111 fprintf(f, "asm(\"bali r15,mcount # X profiling\");\n");
112 }
113
114 fprintf(f, "\t\t%s\n\t\t break;\n", actstring);
115 IFDEBUG(X)
116 if(debug['X']<2) {
117 register int len = 0;
118 fputc('"',astringfile);
119 while(*actstring) {
120 if( *actstring == '\n' ) {
121 fputc('\\', astringfile);
122 len++;
123 fputc('n', astringfile);
124 } else if (*actstring == '\\') {
125 fputc('\\', astringfile);
126 len++;
127 fputc('\\', astringfile);
128 } else if (*actstring == '\"') {
129 fputc('\\', astringfile);
130 len++;
131 fputc('\"', astringfile);
132 } else fputc(*actstring, astringfile);
133 actstring++;
134 len++;
135 }
136 fprintf(astringfile,"\",\n");
137 if (len > LINELEN) {
138 fprintf(stderr, "Action too long: %d\n",len); Exit(-1);
139 }
140 }
141 ENDDEBUG
142
143 return(Actindex);
144 }
145
146 static int Npred=0, Ndefpred=0, Ntrans=0, Ndefevent=0, Nnulla=0;
147
148 void
149 statetable(char *string, struct Object *oldstate, struct Object *newstate, int action, struct Object *event)
150 {
151 register int different;
152
153 IFDEBUG(a)
154 fprintf(OUT,"statetable(%p, %p,%p, 0x%x)\n",
155 string, oldstate, newstate, action);
156 fprintf(OUT,"statetable(%s, %s,%s, 0x%x)\n",
157 string, oldstate->obj_name, newstate->obj_name, action);
158 ENDDEBUG
159
160 if( !action) Nnulla++;
161 if( newstate->obj_kind == OBJ_SET) {
162 fprintf(stderr, "Newstate cannot be a set\n");
163 Exit(-1);
164 }
165 different = (newstate != SameState);
166
167 (void) predtable( oldstate, event, string,
168 action, (newstate->obj_number) * different );
169 IFDEBUG(a)
170 fprintf(OUT,"EXIT statetable\n");
171 ENDDEBUG
172 }
173
174 void
175 stateentry(int idx, int oldstate, int newstate, int action)
176 {
177 extern FILE *statevalfile;
178
179 IFDEBUG(a)
180 fprintf(OUT,"stateentry(0x%x,0x%x,0x%x,0x%x) Statelist@%p, val %p\n",
181 idx, oldstate, newstate,action, &Statelist, Statelist);
182 ENDDEBUG
183
184
185 fprintf(statevalfile, "{0x%x,0x%x},\n", newstate, action);
186 }
187
188 int
189 predtable(struct Object *os, struct Object *oe, char *str, int action, int newstate)
190 {
191 register struct Predicate *p, **q;
192 register int event, state;
193 register struct Object *e, *s;
194 struct Object *firste;
195 extern FILE *statevalfile;
196
197 if (oe == (struct Object *)0 ) {
198 Ndefevent++;
199 fprintf(stderr, "DEFAULT EVENTS aren't implemented; trans ignored\n");
200 return (-1);
201 }
202 Ntrans++;
203 IFDEBUG(g)
204 fprintf(stdout,
205 "PREDTAB: s %5s; e %5s\n", os->obj_kind==OBJ_SET?"SET":"item",
206 oe->obj_kind==OBJ_SET?"SET":"item");
207 ENDDEBUG
208 if (os->obj_kind == OBJ_SET) s = os->obj_members;
209 else s = os;
210 if (oe->obj_kind == OBJ_SET) firste = oe->obj_members;
211 else firste = oe;
212 if(newstate) {
213 fprintf(statevalfile, "{0x%x,0x%x},\n",newstate, action);
214 Index++;
215 }
216 while (s) {
217 if( !newstate ) { /* !newstate --> SAME */
218 /* i.e., use old obj_number */
219 fprintf(statevalfile, "{0x%x,0x%x},\n",s->obj_number, action);
220 Index++;
221 }
222 e = firste;
223 while (e) {
224 event = e->obj_number; state = s->obj_number;
225 IFDEBUG(g)
226 fprintf(stdout,"pred table event=0x%x, state 0x%x\n",
227 event, state);
228 fflush(stdout);
229 ENDDEBUG
230 if( !str /* DEFAULT PREDICATE */) {
231 Ndefpred++;
232 IFDEBUG(g)
233 fprintf(stdout,
234 "DEFAULT pred state 0x%x, event 0x%x, Index 0x%x\n",
235 state, event, Index);
236 fflush(stdout);
237 ENDDEBUG
238 } else
239 Npred++;
240 /* put at END of list */
241 #ifndef LINT
242 IFDEBUG(g)
243 fprintf(stdout,
244 "predicate for event 0x%x, state 0x%x is 0x%x, %s\n",
245 event, state, Index, str);
246 fflush(stdout);
247 ENDDEBUG
248 #endif /* LINT */
249 for( ((q = &Predlist[(event<<Eventshift)+state]),
250 (p = Predlist[(event<<Eventshift)+state]));
251 p ; p = p->p_next ) {
252 q = &p->p_next;
253 }
254
255 p = (struct Predicate *)Malloc(sizeof(struct Predicate));
256 p->p_next = (struct Predicate *)0;
257 p->p_str = str;
258 p->p_index = Index;
259 p->p_transno = transno;
260 *q = p;
261
262 IFDEBUG(g)
263 fprintf(stdout,
264 "predtable index 0x%x, transno %d, E %p, S %p\n",
265 Index, transno, e, s);
266 ENDDEBUG
267
268 e = e->obj_members;
269 }
270 s = s->obj_members;
271 }
272 return Index ;
273 }
274
275 void
276 printprotoerrs(void)
277 {
278 register int e,s;
279
280 fprintf(stderr, "[ Event, State ] without any transitions :\n");
281 for(e = 0; e < Nevents; e++) {
282 fprintf(stderr, "Event 0x%x: states ", e);
283 for(s = 0; s < Nstates; s++) {
284 if( Predlist[(e<<Eventshift)+s] == 0 )
285 fprintf(stderr, "0x%x ", s);
286 }
287 fprintf(stderr, "\n");
288 }
289 }
290
291 #ifndef LINT
292 void
293 dump_predtable(FILE *f)
294 {
295 struct Predicate *p;
296 register int e,s, hadapred;
297 int defaultindex;
298 int defaultItrans;
299
300 #ifdef notdef
301 extern int bytesmalloced;
302 extern int byteswasted;
303
304 fprintf(stdout,
305 " Xebec used %8d bytes of storage, wasted %8d bytes\n",
306 bytesmalloced, byteswasted);
307 #endif /* notdef */
308 fprintf(stdout,
309 " %8d states\n %8d events\n %8d transitions\n",
310 Nstates, Nevents, Ntrans);
311 fprintf(stdout,
312 " %8d predicates\n %8d default predicates used\n",
313 Npred, Ndefpred);
314 fprintf(stdout,
315 " %8d null actions\n",
316 Nnulla);
317
318 putdriver(f, 5);
319 for(e = 0; e < Nevents; e++) { for(s = 0; s < Nstates; s++) {
320 p = Predlist[(e<<Eventshift)+s];
321 hadapred=0;
322 defaultindex=0;
323 defaultItrans=0;
324 if(p) {
325 IFDEBUG(d)
326 fflush(f);
327 ENDDEBUG
328 while(p) {
329 if(p->p_str) {
330 if(!hadapred)
331 fprintf(f, "case 0x%x:\n\t", (e<<Eventshift) + s);
332 hadapred = 1;
333 fprintf(f, "if %s return 0x%x;\n\t else ",
334 p->p_str, p->p_index);
335 } else {
336 if(defaultindex) {
337 fprintf(stderr,
338 "\nConflict between transitions %d and %d: duplicate default \n",
339 p->p_transno, defaultItrans);
340 Exit(-1);
341 }
342 defaultindex = p->p_index;
343 defaultItrans = p->p_transno;
344 }
345 p = p->p_next;
346 }
347 if( hadapred) {
348 fprintf(f, "return 0x%x;\n", defaultindex);
349 }
350 IFDEBUG(d)
351 fflush(f);
352 ENDDEBUG
353 }
354 IFDEBUG(g)
355 fprintf(stdout,
356 "loop: e 0x%x s 0x%x hadapred 0x%x dindex 0x%x for trans 0x%x\n",
357 e, s, hadapred, defaultindex, defaultItrans);
358 ENDDEBUG
359 if ( hadapred ) {
360 /* put a -1 in the array - Predlist is temporary storage */
361 Predlist[(e<<Eventshift)+s] = (struct Predicate *)(-1);
362 } else {
363 /* put defaultindex in the array */
364 /* if defaultindex is zero, then the driver will
365 * cause an erroraction (same as if no default
366 * were given and none of the predicates were true;
367 * also same as if no preds or defaults were given
368 * for this combo)
369 */
370 Predlist[(e<<Eventshift)+s] = (struct Predicate *)(defaultindex);
371 }
372 } }
373 fprintf(f, "default: return 0;\n} /* end switch */\n");
374 #ifdef notdef
375 fprintf(f, "/*NOTREACHED*/return 0;\n} /* _Xebec_index() */\n");
376 #else /* !notdef */
377 fprintf(f, "} /* _Xebec_index() */\n");
378 #endif /* notdef */
379 fprintf(f, "static int inx[%d][%d] = { {", Nevents+1,Nstates);
380 for(s = 0; s< Nstates; s++) fprintf(f, "0,"); /* event 0 */
381 fprintf(f, "},\n");
382
383 for(e = 0; e < Nevents; e++) {
384 fprintf(f, " {");
385 for(s = 0; s < Nstates; s++) {
386 register struct Predicate *xyz = Predlist[(e<<Eventshift)+s];
387 /* this kludge is to avoid a lint msg. concerning
388 * loss of bits
389 */
390 if (xyz == (struct Predicate *)(-1))
391 fprintf(f, "-1,");
392 else
393 fprintf(f, "%p,", Predlist[(e<<Eventshift)+s]);
394 }
395 fprintf(f, " },\n");
396 }
397 fprintf(f, "};");
398 }
399 #endif /* LINT */
400
401 char *
402 stash(char *buf)
403 {
404 register int len;
405 register char *c;
406
407 /* grot */
408 len = strlen(buf);
409 c = Malloc(len+1);
410 #ifdef LINT
411 c =
412 #endif /* LINT */
413 strcpy(c, buf);
414
415 IFDEBUG(z)
416 fprintf(stdout,"stash %s at %p\n", c,c);
417 ENDDEBUG
418 return(c);
419 }
420
421 #ifdef notdef
422 dump_pentry(int event,int state)
423 {
424 register struct Predicate *p, **q;
425
426 for(
427 ((q = &Predlist[(event<<Eventshift) +state]),
428 (p = Predlist[(event<<Eventshift) + state]));
429 p!= (struct Predicate *)0 ; p = p->p_next ) {
430 #ifndef LINT
431 IFDEBUG(a)
432 fprintf(OUT,
433 "dump_pentry for event 0x%x, state 0x%x is 0x%x\n",
434 event, state, p);
435 ENDDEBUG
436 #endif /* LINT */
437 q = &p->p_next;
438 }
439 }
440 #endif /* notdef */
Cache object: 60ece8490a7ba9ecb009b3621cc2834b
|