]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/MAI/bios_emulator/scitech/src/v86bios/parser.y
* Patch by Thomas Frieden, 13 Nov 2002:
[karo-tx-uboot.git] / board / MAI / bios_emulator / scitech / src / v86bios / parser.y
1 %{
2 #include <malloc.h>
3 #include <string.h>
4 #include "v86bios.h"
5 #include "pci.h"
6     
7 #define YYSTYPE unsigned long
8     
9 #define MAX_VAR 0x20
10
11     CARD32 var[MAX_VAR];
12     CARD32 var_mem;
13
14
15 i86biosRegs regs = { 00 };
16
17 enum mem_type { BYTE, WORD, LONG, STRING };
18 union mem_val {
19    CARD32 integer;
20    char *ptr;
21 } rec;
22
23 struct mem {
24     enum mem_type type;
25         union mem_val val;
26     struct mem *next;
27 }; 
28
29  
30 struct device Device = {FALSE,NONE,{0}};
31
32 extern void yyerror(char *s);
33 extern int yylex( void  );
34  
35 static void boot(void);
36 static void dump_mem(CARD32 addr, int len);
37 static void exec_int(int num);
38 static void *add_to_list(enum mem_type type, union mem_val *rec, void *next);
39 static void do_list(struct mem *list, memType addr);
40 static char * normalize_string(char *ptr);
41 %}
42
43 %token TOK_NUM
44 %token TOK_REG_AX
45 %token TOK_REG_BX
46 %token TOK_REG_CX
47 %token TOK_REG_DX
48 %token TOK_REG_DI
49 %token TOK_REG_SI
50 %token TOK_SEG_DS
51 %token TOK_SEG_ES
52 %token TOK_SEP
53 %token TOK_VAR
54 %token TOK_VAR_MEM
55 %token TOK_COMMAND_BOOT
56 %token TOK_COMMAND_EXEC
57 %token TOK_SELECT
58 %token TOK_STRING
59 %token TOK_MODIFIER_BYTE
60 %token TOK_MODIFIER_WORD
61 %token TOK_MODIFIER_LONG
62 %token TOK_MODIFIER_MEMSET
63 %token TOK_COMMAND_MEMSET
64 %token TOK_COMMAND_MEMDUMP
65 %token TOK_COMMAND_QUIT
66 %token TOK_ERROR
67 %token TOK_END
68 %token TOK_ISA
69 %token TOK_PCI
70 %token TOK_BYTE
71 %token TOK_WORD
72 %token TOK_LONG
73 %token TOK_PRINT_PORT
74 %token TOK_IOSTAT
75 %token TOK_PRINT_IRQ
76 %token TOK_PPCI
77 %token TOK_PIP
78 %token TOK_TRACE
79 %token TOK_ON
80 %token TOK_OFF
81 %token TOK_VERBOSE
82 %token TOK_LOG
83 %token TOK_LOGOFF
84 %token TOK_CLSTAT
85 %token TOK_STDOUT
86 %token TOK_HLT
87 %token TOK_DEL
88 %token TOK_IOPERM
89 %token TOK_DUMP_PCI
90 %token TOK_BOOT_BIOS
91 %%
92 input:        | input line  
93 line:          end |  com_reg | com_var | com_select
94               | com_boot | com_memset | com_memdump  | com_quit 
95               | com_exec | hlp | config | verbose | logging | print | clstat 
96               | com_hlt | ioperm | list_pci | boot_bios 
97               | error end  { printf("unknown command\n"); }
98 ;
99 end:           TOK_END
100 ;
101 com_reg:        reg_off val end { *(CARD16*)$1 = $2 & 0xffff; }
102               | reg_seg TOK_SEP reg_off val end {
103                                *(CARD16*)$1 = ($4 & 0xf0000) >> 4;
104                                        *(CARD16*)$3 = ($4 & 0x0ffff);
105                                         }
106               |  reg_off '?' end { printf("0x%x\n",*(CARD16*)$1);}
107               |  reg_seg TOK_SEP reg_off '?' end
108                                      { printf("0x%x:0x%x\n",*(CARD16*)$1,
109                           *(CARD16*)$3); }
110 ;
111 register_read:  reg_seg TOK_SEP reg_off { $$ = (((*(CARD16*)$1) << 4) 
112                                                 | ((*(CARD16*)$3) & 0xffff));
113                                         }
114               | reg_off          { $$ = ((*(CARD16*)$1) & 0xffff); }
115 ;
116 reg_off:        TOK_REG_AX  { $$ = (unsigned long)&(regs.ax); }
117               | TOK_REG_BX  { $$ = (unsigned long)&(regs.bx); }
118               | TOK_REG_CX  { $$ = (unsigned long)&(regs.cx); }
119               | TOK_REG_DX  { $$ = (unsigned long)&(regs.dx); }
120               | TOK_REG_DI  { $$ = (unsigned long)&(regs.di); }
121               | TOK_REG_SI  { $$ = (unsigned long)&(regs.si); }
122 ;
123 reg_seg:        TOK_SEG_DS  { $$ = (unsigned long)&(regs.ds); }
124               | TOK_SEG_ES  { $$ = (unsigned long)&(regs.es); }
125 ;
126 com_var:        TOK_VAR_MEM '?' end { printf("var mem: 0x%x\n",var_mem); }
127           | TOK_VAR '?' end { if ($1 < MAX_VAR)
128           printf("var[%i]: 0x%x\n",(int)$1,var[$1]);
129           else
130           printf("var index %i out of range\n",(int)$1); }
131           | TOK_VAR_MEM val end { var_mem = $2; }    
132               | TOK_VAR val end    { if ($1 <= MAX_VAR)
133                                  var[$1] = $2;
134                               else 
135                                      printf("var index %i out of range\n",(int)$1); }
136               | TOK_VAR error  end { printf("$i val\n"); }
137               | TOK_VAR_MEM error  end { printf("$i val\n"); }
138 ;
139 com_boot:       TOK_COMMAND_BOOT  end { boot(); }
140                 TOK_COMMAND_BOOT error end { boot(); }
141 ;
142 com_select:     TOK_SELECT TOK_ISA end { Device.booted = FALSE;
143                                          Device.type = ISA;
144                      CurrentPci = NULL; }   
145               | TOK_SELECT TOK_PCI val TOK_SEP val TOK_SEP val end
146                                     { Device.booted = FALSE;
147                       Device.type = PCI; 
148                                       Device.loc.pci.bus = $3;
149                                       Device.loc.pci.dev = $5; 
150                                       Device.loc.pci.func = $7; }
151               | TOK_SELECT '?' end
152                                    { switch (Device.type) {
153                                      case ISA:
154                                        printf("isa\n");
155                                        break;
156                                      case PCI:
157                                       printf("pci: %x:%x:%x\n",Device.loc.pci.bus,
158                                               Device.loc.pci.dev,
159                           Device.loc.pci.func);
160                                       break;
161                                  default:
162                                       printf("no device selected\n");
163                                       break;
164                                      }
165                                     }
166               | TOK_SELECT error end { printf("select ? | isa "
167                                          "| pci:bus:dev:func\n"); }
168 ;
169 com_quit:       TOK_COMMAND_QUIT end { return 0; }
170               | TOK_COMMAND_QUIT error end { logoff(); return 0; }
171 ;
172 com_exec:       TOK_COMMAND_EXEC end { exec_int(0x10); }
173           | TOK_COMMAND_EXEC val end { exec_int($2); }
174           | TOK_COMMAND_EXEC error end { exec_int(0x10); }
175 ;
176 com_memdump:    TOK_COMMAND_MEMDUMP val val end { dump_mem($2,$3); }
177               | TOK_COMMAND_MEMDUMP  error  end { printf("memdump start len\n"); }
178
179     
180 ;
181 com_memset:     TOK_COMMAND_MEMSET val list end { do_list((struct mem*)$3,$2);}
182               | TOK_COMMAND_MEMSET error end { printf("setmem addr [byte val] "
183                                                    "[word val] [long val] "
184                                                    "[\"string\"]\n"); }
185 ;
186 list:                              { $$ = 0; } 
187               | TOK_BYTE val list { rec.integer = $2;
188           $$ = (unsigned long)add_to_list(BYTE,&rec,(void*)$3); }
189               | TOK_WORD val list { rec.integer = $2; 
190           $$ = (unsigned long) add_to_list(WORD,&rec,(void*)$3); }
191               | TOK_LONG val list { rec.integer = $2; 
192           $$ = (unsigned long) add_to_list(LONG,&rec,(void*)$3); }
193               | TOK_STRING list { rec.ptr = (void*)$1; 
194           $$ = (unsigned long) add_to_list(STRING,&rec,(void*)$2); }
195 ;
196 val:            TOK_VAR  {  if ($1 > MAX_VAR) {
197                              printf("variable index out of range\n");
198                              $$=0;
199                              } else 
200                             $$ = var[$1]; } 
201               | TOK_NUM  {  $$ = $1; }
202               | register_read
203
204 bool:           TOK_ON   {  $$ = 1; }
205               | TOK_OFF  {  $$ = 0; }
206 ;
207 config:         TOK_PRINT_PORT bool end { Config.PrintPort = $2; } 
208               | TOK_PRINT_PORT '?' end  { printf("print port %s\n",
209                                       Config.PrintPort?"on":"off"); }
210           | TOK_PRINT_PORT error end { printf("pport on | off | ?\n") } 
211               | TOK_PRINT_IRQ bool end  { Config.PrintIrq = $2; } 
212               | TOK_PRINT_IRQ '?' end   { printf("print irq %s\n",  
213                                           Config.PrintIrq?"on":"off"); } 
214           | TOK_PRINT_IRQ error end { printf("pirq on | off | ?\n") } 
215               | TOK_PPCI bool end       { Config.PrintPci = $2; } 
216               | TOK_PPCI '?' end        { printf("print PCI %s\n",
217                                           Config.PrintPci?"on":"off"); } 
218           | TOK_PPCI error end      { printf("ppci on | off | ?\n") } 
219               | TOK_PIP bool end        { Config.PrintIp = $2; } 
220               | TOK_PIP '?' end         { printf("printip %s\n",
221                                       Config.PrintIp?"on":"off"); } 
222           | TOK_PIP error end       { printf("pip on | off | ?\n") } 
223               | TOK_IOSTAT bool end     { Config.IoStatistics = $2; } 
224               | TOK_IOSTAT '?' end      { printf("io statistics %s\n",
225                                       Config.IoStatistics?"on":"off"); } 
226           | TOK_IOSTAT error end    { printf("iostat on | off | ?\n") } 
227               | TOK_TRACE bool end      { Config.Trace = $2; } 
228               | TOK_TRACE '?' end       { printf("trace %s\n",
229                                       Config.Trace ?"on":"off"); } 
230           | TOK_TRACE error end { printf("trace on | off | ?\n") } 
231 ;
232 verbose:        TOK_VERBOSE val end     { Config.Verbose = $2; }
233           | TOK_VERBOSE '?' end     { printf("verbose: %i\n",
234                             Config.Verbose); }
235           | TOK_VERBOSE error end   { printf("verbose val | ?\n"); }
236 ;
237 logging:        TOK_LOG TOK_STRING end  { logon(normalize_string((char*)$2)); }
238           | TOK_LOG '?' end         { if (logging) printf("logfile: %s\n",
239                             logfile);
240                       else printf("no logging\n?"); }
241           | TOK_LOG TOK_OFF end          { logoff(); }
242           | TOK_LOG error end       { printf("log \"<filename>\" | ? |"
243                          " off\n"); }
244 ;
245 clstat:         TOK_CLSTAT end          { clear_stat(); }
246           | TOK_CLSTAT error end    { printf("clstat\n"); } 
247 ;
248 print:          TOK_STDOUT bool end     { nostdout = !$2; }
249                   | TOK_STDOUT '?' end      { printf("print %s\n",nostdout ?
250                         "no":"yes"); }
251           | TOK_STDOUT error end    { printf("print on | off\n"); }
252 ;
253 com_hlt:            TOK_HLT val end         { add_hlt($2); }    
254           | TOK_HLT TOK_DEL val end { del_hlt($3); }
255           | TOK_HLT TOK_DEL end     { del_hlt(21); }
256               | TOK_HLT '?' end         { list_hlt(); }
257           | TOK_HLT error end       { printf(
258                                                "hlt val | del [val] | ?\n"); }
259 ;
260 ioperm:         TOK_IOPERM val val val end { int i,max;
261                                              if ($2 >= 0) {
262                                  max = $2 + $3 - 1;
263                              if (max > IOPERM_BITS) 
264                              max = IOPERM_BITS;
265                                  for (i = $2;i <= max; i++)
266                                 ioperm_list[i] 
267                                                                 = $4>0 ? 1 : 0;
268                           }
269                                            }
270           | TOK_IOPERM '?' end { int i,start;
271                      for (i=0; i <= IOPERM_BITS; i++) {
272                     if (ioperm_list[i]) {
273                        start = i;
274                        for (; i <= IOPERM_BITS; i++) 
275                         if (!ioperm_list[i]) {
276                          printf("ioperm on in "
277                          "0x%x+0x%x\n", start,i-start);
278                          break;
279                         }
280                          }
281                      }
282                                   }
283           | TOK_IOPERM error end { printf("ioperm start len val\n"); }
284 ;
285 list_pci:      TOK_DUMP_PCI end       { list_pci(); }
286              | TOK_DUMP_PCI error end { list_pci(); }
287 ;
288 boot_bios:     TOK_BOOT_BIOS '?' end { if (!BootBios) printf("No Boot BIOS\n");
289                                    else printf("BootBIOS from: %i:%i:%i\n",
290                            BootBios->bus, BootBios->dev,
291                            BootBios->func); }
292              | TOK_BOOT_BIOS error end { printf ("bootbios bus:dev:num\n"); }
293 ;
294 hlp:         '?'  { printf("Command list:\n");
295                     printf(" select isa | pci bus:dev:func\n");
296             printf(" boot\n");
297             printf(" seg:reg val | reg val \n");
298             printf(" $x val | $mem val\n");
299             printf(" setmem addr list; addr := val\n");
300             printf(" dumpmem addr len; addr,len := val\n");
301             printf(" do [val]\n");
302             printf(" quit\n");
303             printf(" ?\n");
304             printf(" seg := ds | es;"
305                " reg := ax | bx | cx | dx | si \n");
306             printf(" val := var | <hex-number> | seg:reg | seg\n");
307             printf(" var := $x | $mem; x := 0..20\n");
308             printf(" list := byte val | word val | long val "
309                "| \"string\"\n");
310                 printf(" pport on | off | ?\n");
311                 printf(" ppci on | off | ?\n");
312                 printf(" pirq on | off | ?\n");
313                 printf(" pip on | off | ?\n");
314                 printf(" trace on | off | ?\n");
315                 printf(" iostat on | off | ?\n");
316             printf(" verbose val\n");
317             printf(" log \"<filename>\" | off | ?\n");
318             printf(" print on | off\n");
319             printf(" hlt val | del [val] | ?\n");
320             printf(" clstat\n");
321             printf(" lpci\n");
322             printf ("bootbios ?\n");
323 }
324 ;
325
326 %%
327
328 static void
329 dump_mem(CARD32 addr, int len)
330 {
331     dprint(addr,len);
332 }
333
334 static void
335 exec_int(int num)
336 {
337     if (num == 0x10) {  /* video interrupt */
338     if (Device.type == NONE) {
339         CurrentPci = PciList;
340         while (CurrentPci) {
341         if (CurrentPci->active)
342             break;
343         CurrentPci = CurrentPci->next;
344         }
345         if (!CurrentPci)
346         Device.type = ISA;
347         else {
348         Device.type = PCI;
349         Device.loc.pci.dev = CurrentPci->dev;
350         Device.loc.pci.bus = CurrentPci->bus;
351         Device.loc.pci.func = CurrentPci->func;
352         }
353     }
354         if (Device.type != ISA) {
355        if (!Device.booted) {
356               if (!CurrentPci || (Device.type == PCI
357                && (!CurrentPci->active
358                    && (Device.loc.pci.dev != CurrentPci->dev
359                  || Device.loc.pci.bus != CurrentPci->bus
360                  || Device.loc.pci.func != CurrentPci->func)))) {
361                 printf("boot the device fist\n");
362             return;
363           }
364            }
365     } else
366        CurrentPci = NULL;
367     } else {
368     Device.booted = FALSE; /* we need this for sanity! */
369     }
370     
371     runINT(num,&regs);
372 }
373
374 static void
375 boot(void)
376 {
377     if (Device.type == NONE) {
378     printf("select a device fist\n");
379     return;
380     }
381     
382     call_boot(&Device);
383 }
384
385 static void *
386 add_to_list(enum mem_type type, union mem_val *rec, void *next)
387 {
388     struct mem *mem_rec = (struct mem *) malloc(sizeof(mem_rec));
389
390     mem_rec->type = type;
391     mem_rec->next = next;
392     
393     switch (type) {
394     case BYTE:
395     case WORD:
396     case LONG:
397     mem_rec->val.integer = rec->integer;
398        break;
399     case STRING:
400     mem_rec->val.ptr = normalize_string(rec->ptr);
401     break;
402     }
403     return mem_rec;
404 }
405
406 static int
407 validRange(int addr,int len)
408 {
409     int end = addr + len;
410
411     if (addr < 0x1000 || end > 0xc0000)
412     return 0;
413     return 1;
414 }
415
416 static void
417 do_list(struct mem *list, memType addr)
418 {
419    struct mem *prev;
420    int len;
421    
422    while (list) {
423     switch (list->type) {
424          case BYTE:
425          if (!validRange(addr,1)) goto error;
426          *(CARD8*)addr = list->val.integer;
427          addr =+ 1;
428              break;     
429          case WORD:
430          if (!validRange(addr,2)) goto error;
431          *(CARD16*)addr = list->val.integer;
432          addr =+ 2;
433              break;     
434          case LONG:
435          if (!validRange(addr,4)) goto error;
436          *(CARD32*)addr = list->val.integer;
437          addr =+ 4;
438              break;
439          case STRING:
440          len = strlen((char*)list->val.ptr);
441          if (!validRange(addr,len)) goto error;
442          memcpy((CARD8*)addr,(void*)list->val.ptr,len);
443          addr =+ len;
444              free(list->val.ptr);
445              break;
446        }     
447        prev = list;
448        list = list->next;
449        free(prev);
450        continue;
451    error:
452        printf("address out of range\n");
453        while (list) {
454        prev = list;
455        list = list->next;
456        free(prev);
457        }
458        break;
459    }
460 }
461
462 static char *
463 normalize_string(char *ptr)
464 {
465     int i = 0, j = 0, c = 0, esc= 0;
466     int size;
467     char *mem_ptr;
468     
469     size = strlen(ptr);
470     mem_ptr = malloc(size);
471     while (1) {
472         switch (*(ptr + i)) {
473         case '\\':
474             if (esc) {
475                 *(mem_ptr + j++) = *(ptr + i);
476                 esc = 0;
477             } else 
478                 esc = 1;
479             break;
480         case '\"':
481             if (esc) {
482                 *(mem_ptr + j++) = *(ptr + i);
483                 esc = 0;
484             } else 
485                 c++;
486             break;
487         default:
488             *(mem_ptr + j++) = *(ptr + i);
489             break;
490         }
491         if (c > 1) {
492             *(mem_ptr + j) = '\0';     
493             break;
494         }
495         i++;
496     }
497     return mem_ptr;
498 }