1/* $NetBSD: procs.c,v 1.15 2009/03/18 10:22:44 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.15 2009/03/18 10:22:44 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 21struct Predicate { 22 int p_index; 23 int p_transno; 24 char *p_str; 25 struct Predicate *p_next; 26}; 27 28struct Stateent { 29 int s_index; 30 int s_newstate; 31 int s_action; 32 struct Stateent *s_next; 33}; 34 35struct Object *SameState = (struct Object *)-1; 36int Index = 0; 37int Nstates = 0; 38int Nevents = 0; 39struct Predicate **Predlist; 40struct Stateent **Statelist; 41extern FILE *astringfile; 42 43int predtable(); 44 45void 46end_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 90int 91acttable(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 146static int Npred=0, Ndefpred=0, Ntrans=0, Ndefevent=0, Nnulla=0; 147 148void 149statetable(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 174void 175stateentry(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 188int 189predtable(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 275void 276printprotoerrs(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 292void 293dump_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 401char * 402stash(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 422dump_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 */ 441