- Fix config.g and the hdama config so everthing builds again.
[coreboot.git] / util / newconfig / config.g
1 # -*- python -*-
2 import sys
3 import os
4 import re
5 import string
6 import types
7
8 import traceback
9
10 warnings = 0
11 errors = 0
12
13 target_dir = ''
14 target_name = ''
15 treetop = ''
16 full_mainboard_path = ''
17 mainboard_path = ''
18 global_options = {}
19 global_options_by_order = []
20 global_option_values = {}
21 global_uses_options = {}
22 global_exported_options = []
23 romimages = {}
24 buildroms = []
25 curimage = 0
26 alloptions = 0 # override uses at top level
27
28 local_path = re.compile(r'^\.')
29 include_pattern = re.compile(r'%%([^%]+)%%')
30
31 # the cpu type for this mainboard
32 cpu_type = 0
33
34 # -----------------------------------------------------------------------------
35 #                    Utility Classes
36 # -----------------------------------------------------------------------------
37
38 class stack:
39         """Used to keep track of the current part or dir"""
40         class __stack_iter:
41                 def __init__ (self, stack):
42                         self.index = 0
43                         self.len = len(stack)
44                         self.stack = stack
45
46                 def __iter__ (self):
47                         return self
48
49                 def next (self):
50                         if (self.index < self.len):
51                                 s = self.stack[self.index]
52                                 self.index = self.index + 1
53                                 return s
54                         raise StopIteration
55
56         def __init__ (self):
57                 self.stack = []
58
59         def __len__ (self):
60                 return len(self.stack)
61
62         def __getitem__ (self, i):
63                 return self.stack[i]
64
65         def __iter__ (self):
66                 return self.__stack_iter(self.stack)
67
68         def push(self, part):
69                 self.stack.append(part)
70
71         def pop(self):
72                 try:
73                         return self.stack.pop()
74                 except IndexError:
75                         return 0
76
77         def tos(self):
78                 try:
79                         return self.stack[-1]
80                 except IndexError:
81                         return 0
82
83         def empty(self):
84                 return (len(self.stack) == 0)
85 partstack = stack()
86 dirstack = stack()
87
88 class debug_info:
89         none = 0
90         gencode = 1
91         dumptree = 2
92         object = 3
93         dict = 4
94         statement = 5
95         dump = 6
96
97         def __init__(self, *level):
98                 self.__level = level
99
100         def setdebug(self, *level):
101                 self.__level = level
102
103         def level(self, level):
104                 return level in self.__level
105
106         def info(self, level, str):
107                 if level in self.__level:
108                         print str
109
110 global debug
111 debug = debug_info(debug_info.none)
112
113 # -----------------------------------------------------------------------------
114 #                    Error Handling
115 # -----------------------------------------------------------------------------
116
117 class location:
118         """Used to keep track of our current location while parsing
119         configuration files"""
120         class __place:
121                 def __init__(self, file, line, command):
122                         self.file = file
123                         self.line = line
124                         self.command = command
125                 def next_line(self, command):
126                         self.line = self.line + 1
127                         self.command = command
128                 def at(self):
129                         return "%s:%d" % (self.file, self.line)
130         
131         def __init__ (self):
132                 self.stack = stack()
133
134         def __str__ (self):
135                 s = ''
136                 for p in self.stack:
137                         if (s == ''):
138                                 s = p.at()
139                         else:
140                                 s = s + '\n' + p.at()
141                 return s
142
143         def file(self):
144                 return self.stack.tos().file
145
146         def line(self):
147                 return self.stack.tos().line
148
149         def command(self):
150                 return self.stack.tos().command
151
152         def push(self, file):
153                 self.stack.push(self.__place(os.path.normpath(file), 0, ""))
154
155         def pop(self):
156                 self.stack.pop()
157
158         def next_line(self, command):
159                 self.stack.tos().next_line(command)
160
161         def at(self):
162                 return self.stack.tos().at()
163 loc = location()
164
165 def error(string):      
166         """Print error message"""
167         global errors, loc
168         errors = errors + 1
169         print "===> ERROR: %s" % string
170         print "%s" % loc
171
172 def fatal(string):      
173         """Print error message and exit"""
174         error(string)
175         exitiferrors()
176
177 def warning(string):
178         """Print warning message"""
179         global warnings, loc
180         warnings = warnings + 1
181         print "===> WARNING: %s" % string
182
183 def notice(string):
184         """Print notice message"""
185         print "===> NOTE: %s" % string
186
187 def exitiferrors():
188         """Exit parser if an error has been encountered"""
189         if (errors != 0):
190                 sys.exit(1)
191
192 def safe_open(file, mode):
193         try:
194                 return open(file, mode)
195         except IOError:
196                 fatal("Could not open file \"%s\"" % file)
197
198 # -----------------------------------------------------------------------------
199 #                    Main classes
200 # -----------------------------------------------------------------------------
201
202 class romimage:
203         """A rom image is the ultimate goal of linuxbios"""
204         def __init__ (self, name):
205                 # name of this rom image
206                 self.name = name
207
208                 # set by 'arch' directive
209                 self.arch = ''
210
211                 # set by 'payload' directive
212                 self.payload = ''
213
214                 # set by 'init' directive
215                 self.initfile = ''
216
217                 # make rules added by 'makerule' directive
218                 self.makebaserules = {}
219
220                 # object files added by 'object' directive
221                 self.objectrules = {}
222
223                 # init object files added by 'initobject' directive
224                 self.initobjectrules = {}
225
226                 # driver files added by 'drive' directive
227                 self.driverrules = {}
228
229                 # loader scripts added by 'ldscript' directive
230                 self.ldscripts = []
231
232                 # user defines added by 'makedefine' directive
233                 self.userdefines = []
234
235                 # files to be included in crt0.S
236                 self.initincludes = {}
237
238                 # as above, but order is preserved
239                 self.initincludesorder = []
240
241                 # transitional flag to support old crtinclude format
242                 self.useinitincludes = 0
243
244                 # instance counter for parts
245                 self.partinstance = 0
246
247                 # chip config files included by the 'config' directive
248                 self.configincludes = {}
249
250                 # root of part tree
251                 self.root = 0
252
253                 # name of target directory specified by 'target' directive
254                 self.target_dir = ''
255
256                 # option values used in rom image
257                 self.values = {}
258
259                 # exported options
260                 self.exported_options = []
261
262         def getname(self):
263                 return self.name
264
265         def getvalues(self):
266                 return self.values
267
268         def setarch(self, arch):
269                 self.arch = arch
270
271         def setpayload(self, payload):
272                 self.payload = payload
273
274         def setinitfile(self, initfile):
275                 self.initfile = initfile
276
277         def getinitfile(self):
278                 return self.initfile
279
280         def addmakerule(self, id):
281                 o = getdict(self.makebaserules, id)
282                 if (o):
283                         warning("rule %s previously defined" % id)
284                 o = makerule(id)
285                 print "We are in addmakerule, add %s\n" % id
286                 setdict(self.makebaserules, id, o)
287
288         def getmakerules(self):
289                 return self.makebaserules
290
291         def getmakerule(self, id):
292                 o = getdict(self.makebaserules, id)
293                 if (o):
294                         return o
295                 fatal("No such make rule \"%s\"" % id)
296
297         def addmakeaction(self, id, str):
298                 o = getdict(self.makebaserules, id)
299                 if (o):
300                         a = dequote(str)
301                         o.addaction(a)
302                         return
303                 fatal("No such rule \"%s\" for addmakeaction" % id)
304
305         def addmakedepend(self, id, str):
306                 o = getdict(self.makebaserules, id)
307                 if (o):
308                         a = dequote(str)
309                         o.adddependency(a)
310                         return
311                 fatal("No such rule \"%s\" for addmakedepend" % id)
312
313         # this is called with an an object name. 
314         # the easiest thing to do is add this object to the current 
315         # component.
316         # such kludgery. If the name starts with '.' then make the 
317         # dependency be on ./thing.x gag me.
318         def addobjectdriver(self, dict, object_name):
319                 global dirstack
320                 suffix = object_name[-2:]
321                 if (suffix == '.o'):
322                         suffix = '.c'
323                 base = object_name[:-2]
324                 type = object_name[-1:]
325                 if (object_name[0] == '.'):
326                         source = base + suffix
327                 else:
328                         source = os.path.join(dirstack.tos(), base + suffix)
329                 object = base + '.o'
330                 debug.info(debug.object, "add object %s source %s" % (object_name, source))
331                 l = getdict(dict, base)
332                 if (l):
333                         warning("object/driver %s previously defined" % base)
334                 setdict(dict, base, [object, source, type, base])
335
336         def addinitobjectrule(self, name):
337                 self.addobjectdriver(self.initobjectrules, name)
338
339         def addobjectrule(self, name):
340                 self.addobjectdriver(self.objectrules, name)
341
342         def adddriverrule(self, name):
343                 self.addobjectdriver(self.driverrules, name)
344
345         def getinitobjectrules(self):
346                 return self.initobjectrules
347
348         def getinitobjectrule(self, name):
349                 o = getdict(self.initobjectrules, name)
350                 if (o):
351                         return o
352                 fatal("No such init object rule \"%s\"" % name)
353
354         def getobjectrules(self):
355                 return self.objectrules
356
357         def getobjectrule(self, name):
358                 o = getdict(self.objectrules, name)
359                 if (o):
360                         return o
361                 fatal("No such object rule \"%s\"" % name)
362
363         def getdriverrules(self):
364                 return self.driverrules
365
366         def getdriverrule(self, name):
367                 o = getdict(self.driverrules, name)
368                 if (o):
369                         return o
370                 fatal("No such driver rule \"%s\"" % name)
371
372         def addldscript(self, path):
373                 self.ldscripts.append(path)
374
375         def getldscripts(self):
376                 return self.ldscripts
377
378         def adduserdefine(self, str):
379                 self.userdefines.append(str)
380
381         def getuserdefines(self):
382                 return self.userdefines
383
384         def addinitinclude(self, str, path):
385                 if (str != 0):
386                         self.useinitincludes = 1
387
388                 debug.info(debug.object, "ADDCRT0: %s -> %s" % (str, path))
389                 o = getdict(self.initincludes, path)
390                 if (o):
391                         warning("init include for %s previously defined" % path)
392                 o = initinclude(str, path)
393                 setdict(self.initincludes, path, o)
394                 self.initincludesorder.append(path)
395
396         def getinitincludes(self):
397                 return self.initincludesorder
398
399         def getinitinclude(self, path):
400                 o = getdict(self.initincludes, path)
401                 if (o):
402                         return o
403                 fatal("No such init include \"%s\"" % path)
404
405         def addconfiginclude(self, part, path):
406                 setdict(self.configincludes, part, path)
407
408         def getconfigincludes(self):
409                 return self.configincludes
410
411         def getincludefilename(self):
412                 if (self.useinitincludes):
413                         return "crt0.S"
414                 else:
415                         return "crt0_includes.h"
416         
417         def newformat(self):
418                 return self.useinitincludes
419
420         def numparts(self):
421                 return self.partinstance
422
423         def newpartinstance(self):
424                 i = self.partinstance
425                 self.partinstance = self.partinstance + 1
426                 return i
427
428         def setroot(self, part):
429                 self.root = part
430
431         def getroot(self):
432                 return self.root
433
434         def settargetdir(self, path):
435                 self.targetdir = path
436
437         def gettargetdir(self):
438                 return self.targetdir
439
440 class buildrom:
441         """A buildrom statement"""
442         def __init__ (self, filename, size, roms):
443                 self.name = filename
444                 self.size = size
445                 self.roms = roms
446         
447         def __len__ (self):
448                 return len(self.roms)
449
450         def __getitem__(self,i):
451                 return self.roms[i]
452
453 class initinclude:
454         """include file for initialization code"""
455         def __init__ (self, str, path):
456                 self.string = str
457                 self.path = path
458
459         def getstring(self):
460                 return self.string
461
462         def getpath(self):
463                 return self.path
464
465 class makerule:
466         """Rule to be included in Makefile"""
467         def __init__ (self, target):
468                 self.target = target
469                 self.dependency = []
470                 self.actions = []
471
472         def addaction(self, action):
473                 self.actions.append(action)
474
475         def adddependency(self, dependency):
476                 self.dependency.append(dependency)
477
478         def gtarget(self):
479                 return self.target
480
481         def gdependency(self):
482                 return self.dependency
483
484         def gaction(self):
485                 return self.actions
486
487 class option:
488         """Configuration option"""
489         def __init__ (self, name):
490                 self.name = name        # name of option
491                 self.loc = 0            # current location
492                 self.used = 0           # option has been used
493                                         # it is undefined)
494                 self.comment = ''       # description of option
495                 self.exportable = 0     # option is able to be exported
496                 self.format = '%s'      # option print format
497                 self.write = []         # parts that can set this option
498
499         def where(self):
500                 return self.loc
501
502         def setcomment(self, comment, loc):
503                 if (self.comment != ''):
504                         print "%s: " % self.name
505                         print "Attempt to modify comment at %s" % loc 
506                         return
507                 self.comment = comment
508
509         def setexportable(self):
510                 self.exportable = 1
511
512         def setnoexport(self):
513                 self.exportable = 0
514
515         def setformat(self, fmt):
516                 self.format = fmt
517
518         def getformat(self):
519                 return self.format
520
521         def setused(self):
522                 if (self.exportable):
523                         self.exported = 1
524                 self.used = 1
525
526         def setwrite(self, part):
527                 self.write.append(part)
528
529         def isexportable(self):
530                 return self.exportable
531
532         def iswritable(self, part):
533                 return (part in self.write)
534
535 class option_value:
536         """Value of a configuration option. The option has a default
537         value which can be changed at any time. Once an option has been
538         set the default value is no longer used."""
539         def __init__(self, name, prev):
540                 self.name = name
541                 self.value = ''
542                 self.set = 0
543                 if (prev):
544                         self.value   = prev.value
545                         self.set     = prev.set
546                 
547
548         def setvalue(self, value):
549                 if ((self.set & 2) == 2):
550                         warning("Changing option %s" % self.name)
551                 else:
552                         self.set |= 2
553                 self.value = value
554
555         def setdefault(self, value):
556                 if ((self.set & 1) == 1):
557                         notice("Changing default value of %s" % self.name)
558                 
559                 if ((self.set & 2) == 0):
560                         self.value = value
561                         self.set |= 1
562
563         def contents(self):
564                 return self.value
565
566         def isset(self):
567                 return (self.set & 2) == 2
568
569
570 class partobj:
571         """A configuration part"""
572         def __init__ (self, image, dir, parent, part, type_name, instance_name, link, chip_or_device):
573                 debug.info(debug.object, "partobj dir %s parent %s part %s" \
574                                 % (dir, parent, part))
575
576                 # romimage that is configuring this part
577                 self.image = image
578
579                 # links for static device tree
580                 self.children = 0
581                 self.siblings = 0
582                 self.chip_or_device = chip_or_device
583
584                 # list of init code files
585                 self.initcode = []
586
587                 # initializers for static device tree
588                 self.registercode = {}
589
590                 # part name
591                 self.part = part
592
593                 # type name of this part
594                 self.type_name = type_name
595
596                 # object files needed to build this part
597                 self.objects = []
598
599                 # directory containg part files
600                 self.dir = dir
601
602                 # instance number, used to distinguish anonymous
603                 # instances of this part
604                 self.instance = image.newpartinstance()
605                 debug.info(debug.object, "INSTANCE %d" % self.instance)
606
607                 # Options used by this part
608                 self.uses_options = {}
609
610                 # Name of chip config file (0 if not needed)
611                 self.chipconfig = 0
612
613                 # Flag to indicate that we have generated type
614                 # definitions for this part (only want to do it once)
615                 self.done_types = 0
616
617                 # Path to the device
618                 self.path = ""
619
620                 # Resources of the device
621                 self.resoruce = ""
622                 self.resources = 0
623
624                 # Enabled state of the device
625                 self.enabled = 1
626
627                 # Link from parent device
628                 if ((link < 0) or (link > 16)):
629                         fatal("Invalid link")
630                 self.link = link
631                 
632                 # If no instance name is supplied then generate
633                 # a unique name
634                 if (instance_name == 0):
635                         self.instance_name = self.type_name + \
636                                         "_dev%d" % self.instance
637                         self.chipinfo_name = "%s_info_%d" \
638                                         % (self.type_name, self.instance)
639                 else:
640                         self.instance_name = instance_name
641                         self.chipinfo_name = "%s_info_%d" % (self.instance_name, self.instance)
642                 
643                 # Link this part into the tree
644                 if (parent and (part != 'arch')):
645                         debug.info(debug.gencode, "add to parent")
646                         self.parent   = parent
647                         # add current child as my sibling, 
648                         # me as the child.
649                         if (parent.children):
650                                 debug.info(debug.gencode, "add %s (%d) as sibling" % (parent.children.dir, parent.children.instance))
651                                 youngest = parent.children
652                                 while(youngest.siblings):
653                                         youngest = youngest.siblings
654                                 youngest.siblings = self
655                         else:
656                                 parent.children = self
657                 else:
658                         self.parent = self
659
660         def info(self):
661                 return "%s: %s" % (self.part, self.type)
662         def type(self):
663                 return self.chip_or_device
664
665         def dumpme(self, lvl):
666                 """Dump information about this part for debugging"""
667                 print "%d: part %s" % (lvl, self.part)
668                 print "%d: instance %d" % (lvl, self.instance)
669                 print "%d: dir %s" % (lvl,self.dir)
670                 print "%d: type_name %s" % (lvl,self.type_name)
671                 print "%d: parent %s" % (lvl,self.parent.part)
672                 print "%d: parent dir %s" % (lvl,self.parent.dir)
673                 if (self.children):
674                         print "%d: child %s" % (lvl, self.children.dir)
675                 if (self.siblings):
676                         print "%d: siblings %s" % (lvl, self.siblings.dir)
677                 print "%d: initcode " % lvl
678                 for i in self.initcode:
679                         print "\t%s" % i
680                 print "%d: registercode " % lvl
681                 for f, v in self.registercode.items():
682                         print "\t%s = %s" % (f, v)
683                 print "\n"
684
685         def firstchilddevice(self):
686                 """Find the first device in the children link."""
687                 kid = self.children
688                 while (kid):
689                         if (kid.chip_or_device == 'device'):
690                                 return kid
691                         else:
692                                 kid = kid.children
693                 return 0
694
695         def firstparentdevice(self):
696                 """Find the first device in the parent link."""
697                 parent = self.parent
698                 while (parent):
699                         if ((parent.parent == parent) or (parent.chip_or_device == 'device')):
700                                 return parent
701                         else:
702                                 parent = parent.parent
703                 fatal("Device %s has no device parent; this is a config file error" % self.type_name)
704
705         def firstparentchip(self):
706                 """Find the first chip in the parent link."""
707                 parent = self.parent
708                 while (parent):
709                         if ((parent.parent == parent) or (parent.chip_or_device == 'chip')):
710                                 return parent
711                         else:
712                                 parent = parent.parent
713                 fatal("Device %s has no chip parent; this is a config file error" % self.type_name)
714
715         def firstsiblingdevice(self):
716                 """Find the first device in the sibling link."""
717                 sibling = self.siblings
718                 while(sibling):
719                         if (sibling.chip_or_device == 'device'):
720                                 return sibling
721                         else:
722                                 sibling = sibling.children
723                 return 0                
724
725         def gencode(self, file, pass_num):
726                 """Generate static initalizer code for this part. Two passes
727                 are used - the first generates type information, and the second
728                 generates instance information"""
729                 if (pass_num == 0):
730                         if (self.chip_or_device == 'chip'):
731                                 return;
732                         else:
733                                 if (self.instance):
734                                         file.write("struct device %s;\n" \
735                                                 % self.instance_name)
736                                 else:
737                                         file.write("struct device dev_root;\n")
738                         return
739                 # This is pass the second, which is pass number 1
740                 # this is really just a case statement ...
741                 if ((self.instance) and (self.chip_or_device == 'chip') and (self.chipconfig)):
742                         debug.info(debug.gencode, "gencode: chipconfig(%d)" % \
743                                         self.instance)
744                         file.write("struct %s_config %s" % (self.type_name ,\
745                                         self.chipinfo_name))
746                         if (self.registercode):
747                                 file.write("\t= {\n")
748                                 for f, v in self.registercode.items():
749                                         file.write( "\t.%s = %s,\n" % (f, v))
750                                 file.write("};\n")
751                         else:
752                                 file.write(";")
753                         file.write("\n")
754                         return
755                         
756                 if (self.chipconfig):
757                         debug.info(debug.gencode, "gencode: chipconfig(%d)" % \
758                                         self.instance)
759                         file.write("struct %s_config %s" % (self.type_name ,\
760                                         self.chipinfo_name))
761                         if (self.registercode):
762                                 file.write("\t= {\n")
763                                 for f, v in self.registercode.items():
764                                         file.write( "\t.%s = %s,\n" % (f, v))
765                                 file.write("};\n")
766                         else:
767                                 file.write(";")
768                         file.write("\n")
769
770                 if (self.instance == 0):
771                         self.instance_name = "dev_root"
772                         file.write("struct %s_config %s_info_%s;\n" % (self.type_name, self.type_name, self.instance))
773                         file.write("struct device dev_root = {\n")
774                         file.write("\t.ops = &default_dev_ops_root,\n")
775                         file.write("\t.bus = &dev_root.link[0],\n")
776                         file.write("\t.path = { .type = DEVICE_PATH_ROOT },\n")
777                         file.write("\t.enabled = 1,\n\t.links = 1,\n")
778                         file.write("\t.link = {\n\t\t[0] = {\n")
779                         file.write("\t\t\t.dev=&dev_root,\n\t\t\t.link = 0,\n")
780                         file.write("\t\t\t.children = &%s,\n" % self.firstchilddevice().instance_name)
781                         file.write("\t\t},\n")
782                         file.write("\t},\n")
783                         if (self.chipconfig != 0):
784                                 file.write("\t.chip_control = &%s_control,\n" % self.type_name)
785                                 file.write("\t.chip_info = &%s_info_%s,\n" % (self.type_name, self.instance))
786                         file.write("};\n")
787                         return
788
789                 file.write("struct device %s = {\n" % self.instance_name)
790                 file.write("\t.ops = 0,\n")
791                 file.write("\t.bus = &%s.link[0],\n" % self.firstparentdevice().instance_name)
792                 file.write("\t.path = {%s},\n" % self.path)
793                 file.write("\t.enabled = %d,\n" % self.enabled)
794                 if (self.resources):
795                         file.write("\t.resources = %d,\n" % self.resources)
796                         file.write("\t.resource = {%s\n\t },\n" % self.resource)
797                 file.write("\t.links = 1,\n")
798                 file.write("\t.link = {\n\t\t[0] = {\n")
799                 file.write("\t\t\t.dev=&%s,\n\t\t\t.link = 0,\n" % self.instance_name)
800                 if (self.firstchilddevice()):
801                         file.write("\t\t\t.children = &%s,\n" % self.firstchilddevice().instance_name)
802                 file.write("\t\t},\n")
803                 file.write("\t},\n")
804                 sibling = self.firstsiblingdevice();
805                 if (sibling):
806                         file.write("\t.sibling = &%s,\n" % sibling.instance_name)
807                 if (self.chipconfig != 0):
808                         file.write("\t.chip_control = &%s_control,\n" % self.firstparentchip().type_name)
809                         file.write("\t.chip_info = &%s_info_%s,\n" % (self.firstparentchip().type_name, self.firstparentchip().instance))
810                 file.write("};\n")
811                 return
812
813
814
815                 file.write("\t/* %s %s */\n" % (self.part, self.dir))
816                 file.write("\t.link = %d,\n" % (self.link))
817 #               if (self.path != ""):
818 #                       file.write("\t.path = { %s\n\t},\n" % (self.path) )
819                 if (self.siblings):
820                         debug.info(debug.gencode, "gencode: siblings(%d)" \
821                                 % self.siblings.instance)
822                         file.write("\t.next = &%s,\n" \
823                                 % self.siblings.instance_name)
824                 else:
825                         file.write("\t.next = 0,\n")
826                 if (self.children):
827                         debug.info(debug.gencode, "gencode: children(%d)" \
828                                 % self.children.instance)
829                         file.write("\t.children = &%s,\n" \
830                                 % self.children.instance_name)
831                 else:
832                         file.write("\t.children = 0,\n")
833                 if (self.chipconfig):
834                         # set the pointer to the structure for all this
835                         # type of part
836                         file.write("\t.control= &%s_control,\n" % \
837                                         self.type_name )
838                         # generate the pointer to the isntance
839                         # of the chip struct
840                         file.write("\t.chip_info = (void *) &%s,\n" \
841                                         % self.chipinfo_name)
842                 else:
843                         file.write("\t.control= 0,\n")
844                         file.write("\t.chip_info= 0,\n")
845                 file.write("};\n")
846                 
847         def addinit(self, code):
848                 """Add init file to this part"""
849                 self.initcode.append(code)
850                 
851         def addconfig(self, path):
852                 """Add chip config file to this part"""
853                 self.chipconfig = os.path.join(self.dir, path)
854                 self.image.addconfiginclude(self.type_name, self.chipconfig)
855
856         def addregister(self, field, value):
857                 """Register static initialization information"""
858                 field = dequote(field)
859                 value = dequote(value)
860                 setdict(self.registercode, field, value)
861
862         def set_enabled(self, enabled):
863                 self.enabled = enabled
864
865         def start_resources(self):
866                 self.resource = ""
867                 self.resources = 0
868
869         def end_resources(self):
870                 self.resource = "%s" % (self.resource)
871
872         def add_resource(self, type, index, value):
873                 """ Add a resource to a device """
874                 self.resource = "%s\n\t\t{ .flags=%s, .index=0x%x, .base=0x%x}," % (self.resource, type, index, value)
875                 self.resources = self.resources + 1
876                 
877         def addpcipath(self, slot, function):
878                 """ Add a relative pci style path from our parent to this device """
879                 if ((slot < 0) or (slot > 0x1f)):
880                         fatal("Invalid device id")
881                 if ((function < 0) or (function > 7)):
882                         fatal("Invalid function")
883                 self.path = ".type=DEVICE_PATH_PCI,.u={.pci={ .devfn = PCI_DEVFN(0x%x,%d)}}" % (slot, function)
884
885         def addpnppath(self, port, device):
886                 """ Add a relative path to a pnp device hanging off our parent """
887                 if ((port < 0) or (port > 65536)):
888                         fatal("Invalid port")
889                 if ((device < 0) or (device > 0xff)):
890                         fatal("Invalid device")
891                 self.path = ".type=DEVICE_PATH_PNP,.u={.pnp={ .port = 0x%x, .device = 0x%x }}" % (port, device)
892                 
893         def addi2cpath(self, device):
894                 """ Add a relative path to a i2c device hanging off our parent """
895                 if ((device < 0) or (device > 0x7f)):
896                         fatal("Invalid device")
897                 self.path = ".type=DEVICE_PATH_I2C,.u={.i2c={ .device = 0x%x }}" % (device)
898
899         def addapicpath(self, apic_id):
900                 """ Add a relative path to a cpu device hanging off our parent """
901                 if ((apic_id < 0) or (apic_id > 255)):
902                         fatal("Invalid device")
903                 self.path = ".type=DEVICE_PATH_APIC,.u={.apic={ .apic_id = 0x%x }}" % (apic_id)
904     
905         def addpci_domainpath(self, pci_domain):
906                 """ Add a pci_domain number to a chip """
907                 if ((pci_domain < 0) or (pci_domain > 0xffff)):
908                         fatal("Invalid pci_domain: 0x%x is out of the range 0 to 0xffff" % pci_domain)
909                 self.path = ".type=DEVICE_PATH_PCI_DOMAIN,.u={.pci_domain={ .domain = 0x%x }}" % (pci_domain)
910     
911         def addapic_cluster(self, cluster):
912                 """ Add a pci_domain number to a chip """
913                 if ((cluster < 0) or (cluster > 15)):
914                         fatal("Invalid apic cluster: %d is out of the range 0 to ff" % cluster)
915                 self.path = ".type=DEVICE_PATH_APIC_CLUSTER,.u={.apic_cluster={ .cluster = 0x%x }}" % (cluster)
916     
917         def usesoption(self, name):
918                 """Declare option that can be used by this part"""
919                 global global_options
920                 o = getdict(global_options, name)
921                 if (o == 0):
922                         fatal("can't use undefined option %s" % name)
923                 o1 = getdict(self.uses_options, name)
924                 if (o1):
925                         return
926                 setdict(self.uses_options, name, o)
927                 exportoption(o, self.image.exported_options)
928
929 # -----------------------------------------------------------------------------
930 #                    statements 
931 # -----------------------------------------------------------------------------
932
933 def getdict(dict, name):
934         if name not in dict.keys(): 
935                 debug.info(debug.dict, "Undefined: %s" % name)
936                 return 0
937         v = dict.get(name, 0)
938         debug.info(debug.dict, "getdict %s returning %s" % (name, v))
939         return v
940
941 def setdict(dict, name, value):
942         debug.info(debug.dict, "setdict sets %s to %s" % (name, value))
943         dict[name] = value
944
945 # options. 
946 # to create an option, it has to not exist. 
947 # When an option value is fetched, the fact that it was used is 
948 # remembered. 
949 # Legal things to do:
950 # set a default value, then set a real value before the option is used.
951 # set a value, try to set a default, default silently fails.
952 # Illegal:
953 # use the value, then try to set the value
954
955 def newoption(name):
956         global global_options, global_options_by_order
957         o = getdict(global_options, name)
958         if (o):
959                 fatal("option %s already defined" % name)
960         o = option(name)
961         setdict(global_options, name, o)
962         global_options_by_order.append(name)
963
964 def newoptionvalue(name, image):
965         g = getdict(global_option_values, name)
966         v = option_value(name, g)
967         if (image):
968                 setdict(image.getvalues(), name, v)
969         else:
970                 setdict(global_option_values, name, v)
971         return v
972
973 def getoptionvalue(name, op, image):
974         global global_option_values
975         #print "getoptionvalue name %s op %s image %s\n" % (name, op,image)
976         if (op == 0):
977                 print_stack()
978                 fatal("Option %s undefined (missing use command?)" % name)
979         if (image):
980                 v = getdict(image.getvalues(), name)
981         else:
982                 v = getdict(global_option_values, name)
983         return v
984
985 def getoption(name, image):
986         """option must be declared before being used in a part
987         if we're not processing a part, then we must
988         be at the top level where all options are available"""
989
990         global global_uses_options, alloptions, curimage
991
992         #print "getoption: name %s image %s alloptions %s curimage %s\n\n" % (name, image, alloptions, curimage)
993         curpart = partstack.tos()
994         if (alloptions):
995                 o = getdict(global_options, name)
996         elif (curpart):
997                 o = getdict(curpart.uses_options, name)
998                 if (o == 0):
999                         print "curpart.uses_optins is %s\n" % curpart.uses_options
1000         else:
1001                 o = getdict(global_uses_options, name)
1002         v = getoptionvalue(name, o, image)
1003         if (v == 0):
1004                 v = getoptionvalue(name, o, 0)
1005         if (v == 0):
1006                 fatal("No value for option %s" % name)
1007         val = v.contents()
1008         if (not (type(val) is types.StringType)):
1009                 return v.contents()
1010         if (val == '' or val[0] != '{'):
1011                 return v.contents()
1012         s = curimage
1013         curimage = image
1014         val = parse('delexpr', val)
1015         curimage = s
1016         exitiferrors()
1017         return val
1018
1019 def setoption(name, value, imp):
1020         """Set an option from within a configuration file. Normally this
1021         is only permitted in the target (top level) configuration file.
1022         If 'imp' is true, then set an option implicitly (e.g. 'arch' 
1023         and 'mainboard' statements). Implicit options can be set anywhere 
1024         the statements are legal, but also performs an implicit 'uses' 
1025         for the option"""
1026
1027         global loc, global_options, global_option_values, curimage
1028
1029         curpart = partstack.tos()
1030         if (not imp and curpart):
1031                 fatal("Options may only be set in target configuration file")
1032         if (imp):
1033                 usesoption(name)
1034         if (curpart):
1035                 o = getdict(curpart.uses_options, name)
1036         else:
1037                 o = getdict(global_uses_options, name)
1038         if (not o):
1039                 fatal("Attempt to set nonexistent option %s (missing USES?)" % name)
1040         v = getoptionvalue(name, o, curimage)
1041         if (v == 0):
1042                 v = newoptionvalue(name, curimage)
1043         v.setvalue(value)
1044
1045 def exportoption(op, exported_options):
1046         if (not op.isexportable()):
1047                 return
1048         if (not op in exported_options):
1049                 exported_options.append(op)
1050
1051 def setdefault(name, value, isdef):
1052         """Set the default value of an option from within a configuration 
1053         file. This is permitted from any configuration file, but will
1054         result in a warning if the default is set more than once.
1055         If 'isdef' is set, we're defining the option in Options.lb so
1056         there is no need for 'uses'."""
1057
1058         global loc, global_options, curimage
1059
1060         if (isdef):
1061                 o = getdict(global_options, name)
1062                 if (not o):
1063                         return
1064                 image = 0
1065         else:
1066                 curpart = partstack.tos()
1067                 if (curpart):
1068                         o = getdict(curpart.uses_options, name)
1069                 else:
1070                         o = getdict(global_uses_options, name)
1071                 if (not o):
1072                         fatal("Attempt to set default for nonexistent option %s (missing USES?)" % name)
1073                 image = curimage
1074
1075         v = getoptionvalue(name, o, image)
1076         if (v == 0):
1077                 v = newoptionvalue(name, image)
1078         v.setdefault(value)
1079
1080 def setnodefault(name):
1081         global loc, global_options
1082         o = getdict(global_options, name)
1083         if (not o):
1084                 return
1085         v = getdict(global_option_values, name)
1086         if (v != 0):
1087                 warning("removing default for %s" % name)
1088                 del global_option_values[name]
1089
1090 def setcomment(name, value):
1091         global loc, global_options
1092         o = getdict(global_options, name)
1093         if (not o):
1094                 fatal("setcomment: %s not here" % name)
1095         o.setcomment(value, loc)
1096
1097 def setexported(name):
1098         global global_options
1099         o = getdict(global_options, name)
1100         if (not o):
1101                 fatal("setexported: %s not here" % name)
1102         o.setexportable()
1103         global_exported_options.append(o)
1104
1105 def setnoexport(name):
1106         global global_options
1107         o = getdict(global_options, name)
1108         if (not o):
1109                 fatal("setnoexport: %s not here" % name)
1110         o.setnoexport()
1111         if (o in global_exported_options):
1112                 global_exported_options.remove(o)
1113
1114 def setexportable(name):
1115         global global_options
1116         o = getdict(global_options, name)
1117         if (not o):
1118                 fatal("setexportable: %s not here" % name)
1119         o.setexportable()
1120
1121 def setformat(name, fmt):
1122         global global_options
1123         o = getdict(global_options, name)
1124         if (not o):
1125                 fatal("setformat: %s not here" % name)
1126         o.setformat(fmt)
1127
1128 def getformated(name, image):
1129         global global_options, global_option_values
1130         o = getdict(global_options, name)
1131         v = getoption(name, image)
1132         f = o.getformat()
1133         return (f % v)
1134
1135 def setwrite(name, part):
1136         global global_options
1137         o = getdict(global_options, name)
1138         if (not o):
1139                 fatal("setwrite: %s not here" % name)
1140         o.setwrite(part)
1141
1142 def hasvalue(name, image):
1143         global global_options
1144         o = getdict(global_options, name)
1145         if (o == 0):
1146                 return 0
1147         v = 0
1148         if (image):
1149                 v = getdict(image.getvalues(), name)
1150         if (v == 0):
1151                 v = getdict(global_option_values, name)
1152         return (v != 0)
1153
1154 def isset(name, part):
1155         global global_uses_options, global_option_values, curimage
1156         if (part):
1157                 o = getdict(part.uses_options, name)
1158         else:
1159                 o = getdict(global_uses_options, name)
1160         if (o == 0):
1161                 return 0
1162         v = 0
1163         if (curimage):
1164                 v = getdict(curimage.getvalues(), name)
1165         if (v == 0):
1166                 v = getdict(global_option_values, name)
1167         return (v != 0 and v.isset())
1168
1169 def usesoption(name):
1170         global global_options, global_uses_options
1171         curpart = partstack.tos()
1172         if (curpart):
1173                 curpart.usesoption(name)
1174                 return
1175         o = getdict(global_options, name)
1176         if (o == 0):
1177                 fatal("Can't use undefined option %s" % name)
1178         o1 = getdict(global_uses_options, name)
1179         if (o1):
1180                 return
1181         setdict(global_uses_options, name, o)
1182         exportoption(o, global_exported_options)
1183
1184 def validdef(name, defval):
1185         global global_options
1186         o = getdict(global_options, name)
1187         if (not o):
1188                 fatal("validdef: %s not here" % name)
1189         if ((defval & 1) != 1):
1190             fatal("Must specify default value for option %s" % name)
1191         if ((defval & 2) != 2):
1192             fatal("Must specify export for option %s" % name)
1193         if ((defval & 4) != 4):
1194             fatal("Must specify comment for option %s" % name)
1195
1196 def loadoptions(path, file, rule):
1197         file = os.path.join('src', path, file)
1198         optionsfile = os.path.join(treetop, file)
1199         fp = safe_open(optionsfile, 'r')
1200         loc.push(file)
1201         if (not parse(rule, fp.read())):
1202                 fatal("Could not parse file")
1203         loc.pop()
1204
1205 def addinit(path):
1206         global curimage, dirstack
1207         if (path[0] == '/'):
1208                 curimage.setinitfile(treetop + '/src/' + path)
1209         else:
1210                 curimage.setinitfile(dirstack.tos() + '/' + path)
1211         print "Adding init file: %s" % path
1212
1213 def addconfig(path):
1214         global partstack
1215         curpart = partstack.tos()
1216         curpart.addconfig(path)
1217
1218 def addregister(field, value):
1219         global partstack
1220         curpart = partstack.tos()
1221         curpart.addregister(field, value)
1222
1223 def addcrt0include(path):
1224         """we do the crt0include as a dictionary, so that if needed we
1225         can trace who added what when. Also it makes the keys
1226         nice and unique."""
1227         global curimage
1228         curimage.addinitinclude(0, path)
1229
1230 def addinitinclude(str, path):
1231         global curimage
1232         curimage.addinitinclude(dequote(str), path)
1233
1234 def addldscript(path):
1235         global curimage, dirstack
1236         curdir = dirstack.tos()
1237         if (path[0] == '/'):
1238                 fullpath =  treetop + '/src/' + path
1239         else:
1240                 fullpath = curdir + '/' + path
1241         debug.info(debug.statement, "fullpath :%s: curdir :%s: path :%s:" % (fullpath, curdir, path))
1242         curimage.addldscript(fullpath)
1243
1244 def payload(path):
1245         global curimage
1246         curimage.setpayload(path)
1247         adduserdefine("PAYLOAD:=%s"%path)
1248
1249 def startromimage(name):
1250         global romimages, curimage, target_dir, target_name
1251         curpart = partstack.tos()
1252         print "Configuring ROMIMAGE %s Curimage %s" % (name, curimage)
1253         print "Curpart is %s\n" % curpart
1254         o = getdict(romimages, name)
1255         if (o):
1256                 fatal("romimage %s previously defined" % name)
1257         curimage = romimage(name)
1258         curimage.settargetdir(os.path.join(target_dir, name))
1259         #o = partobj(curimage, target_dir, 0, 'board', target_name)
1260         #curimage.setroot(o)
1261         setdict(romimages, name, curimage)
1262         dodir('/config', 'Config.lb')
1263
1264 def endromimage():
1265         global curimage
1266         mainboard()
1267         print "End ROMIMAGE"
1268         curimage = 0
1269         #curpart = 0
1270
1271 def mainboardsetup(path):
1272         global full_mainboard_path, mainboard_path
1273         mainboard_path = os.path.join('mainboard', path)
1274         loadoptions(mainboard_path, 'Options.lb', 'mainboardvariables')
1275         full_mainboard_path = os.path.join(treetop, 'src', 'mainboard', path)
1276         vendor = re.sub("/.*", "", path)
1277         part_number = re.sub("[^/]*/", "", path)
1278         setdefault('MAINBOARD', full_mainboard_path, 0)
1279         setdefault('MAINBOARD_VENDOR', vendor, 0)
1280         setdefault('MAINBOARD_PART_NUMBER', part_number, 0)
1281
1282 def mainboard():
1283         global curimage, dirstack, partstack
1284         file = 'Config.lb'
1285         partdir = mainboard_path
1286         srcdir = os.path.join(treetop, 'src')
1287         fulldir = os.path.join(srcdir, partdir)
1288         type_name = flatten_name(partdir)
1289         newpart = partobj(curimage, fulldir, partstack.tos(), 'mainboard', \
1290                 type_name, 0, 0, 'chip')
1291         print "Configuring PART %s" % (type)
1292         partstack.push(newpart)
1293         #print "  new PART tos is now %s\n" %partstack.tos().info()
1294         dirstack.push(fulldir)
1295         loadoptions(mainboard_path, 'Options.lb', 'mainboardvariables')
1296         # special case for 'cpu' parts.
1297         # we could add a new function too, but this is rather trivial.
1298         # if the part is a cpu, and we haven't seen it before,
1299         # arrange to source the directory /cpu/'type'
1300         doconfigfile(srcdir, partdir, file, 'cfgfile')
1301         curimage.setroot(partstack.tos())
1302         partpop()
1303
1304 def addbuildrom(filename, size, roms):
1305         global buildroms
1306         print "Build ROM size %d" % size
1307         b = buildrom(filename, size, roms)
1308         buildroms.append(b)
1309
1310 def addinitobject(object_name):
1311         global curimage
1312         curimage.addinitobjectrule(object_name)
1313
1314 def addobject(object_name):
1315         global curimage
1316         curimage.addobjectrule(object_name)
1317
1318 def adddriver(driver_name):
1319         global curimage
1320         curimage.adddriverrule(driver_name)
1321
1322 def target(name):
1323         global target_dir, target_name
1324         print "Configuring TARGET %s" % name
1325         target_name = name
1326         target_dir = os.path.join(os.path.dirname(loc.file()), name)
1327         if not os.path.isdir(target_dir):
1328                 print "Creating directory %s" % target_dir
1329                 os.makedirs(target_dir)
1330         print "Will place Makefile, crt0.S, etc. in %s" % target_dir
1331
1332
1333 def cpudir(path):
1334         global cpu_type
1335         if (cpu_type and (cpu_type != path)):
1336                 fatal("Two different CPU types: %s and %s" % (cpu_type, path))
1337         srcdir = "/cpu/%s" % path
1338         dodir(srcdir, "Config.lb")
1339         cpu_type = path
1340         
1341 def devicepart(type):
1342         global curimage, dirstack, partstack
1343         newpart = partobj(curimage, 0, partstack.tos(), type, \
1344                         '', 0, 0, 'device')
1345         print "Configuring PART %s" % (type)
1346         partstack.push(newpart)
1347         #print "  new PART tos is now %s\n" %partstack.tos().info()
1348         # just push TOS, so that we can pop later. 
1349         dirstack.push(dirstack.tos())
1350         
1351 def part(type, path, file, name, link):
1352         global curimage, dirstack, partstack
1353         partdir = os.path.join(type, path)
1354         srcdir = os.path.join(treetop, 'src')
1355         fulldir = os.path.join(srcdir, partdir)
1356         type_name = flatten_name(partdir)
1357         newpart = partobj(curimage, fulldir, partstack.tos(), type, \
1358                         type_name, name, link, 'chip')
1359         #print "Configuring PART %s, path %s" % (type, path)
1360         partstack.push(newpart)
1361         #print "  new PART tos is now %s\n" %partstack.tos().info()
1362         dirstack.push(fulldir)
1363         # special case for 'cpu' parts. 
1364         # we could add a new function too, but this is rather trivial.
1365         # if the part is a cpu, and we haven't seen it before, 
1366         # arrange to source the directory /cpu/'type'
1367         if (type == 'cpu'):
1368                 cpudir(path)
1369         else:
1370                 doconfigfile(srcdir, partdir, file, 'cfgfile')
1371
1372 def partpop():
1373         global dirstack, partstack
1374         curpart = partstack.tos()
1375         if (curpart == 0):
1376                 fatal("Trying to pop non-existent part")
1377         print "End PART %s" % curpart.part
1378         # Warn if options are used without being set in this part
1379         for op in curpart.uses_options.keys():
1380                 if (not isset(op, curpart)):
1381                         notice("Option %s using default value %s" % (op, getformated(op, curpart.image)))
1382         oldpart = partstack.pop()
1383         dirstack.pop()
1384         #print "partstack.pop, TOS is now %s\n" % oldpart.info()
1385
1386 def dodir(path, file):
1387         """dodir is like part but there is no new part"""
1388         global dirstack
1389         # if the first char is '/', it is relative to treetop, 
1390         # else relative to curdir
1391         # os.path.join screws up if the name starts with '/', sigh.
1392         print "Configuring DIR %s" % os.path.join(path, file)
1393         if (path[0] == '/'):
1394                 fullpath = os.path.join(treetop, 'src')
1395                 path = re.sub('^/*', '', path)
1396         else:
1397                 fullpath = dirstack.tos()
1398         debug.info(debug.statement, "DODIR: path %s, fullpath %s" % (path, fullpath))
1399         dirstack.push(os.path.join(fullpath, path))
1400         doconfigfile(fullpath, path, file, 'cfgfile')
1401         dirstack.pop()
1402
1403 def lookup(name):
1404         global curimage
1405         return getoption(name, curimage)
1406
1407 def addrule(id):
1408         global curimage
1409         print "ADDRULE: %s\n" %id
1410         curimage.addmakerule(id)
1411         
1412 def adduserdefine(str):
1413         global curimage
1414         curimage.adduserdefine(str)
1415
1416 def addaction(id, str):
1417         global curimage
1418         curimage.addmakeaction(id, str)
1419
1420 def adddep(id, str):
1421         global curimage
1422         curimage.addmakedepend(id, str)
1423
1424 def setarch(my_arch):
1425         """arch is 'different' ... darn it."""
1426         global curimage
1427         print "SETTING ARCH %s\n" % my_arch
1428         curimage.setarch(my_arch)
1429         setdefault('ARCH', my_arch, 1)
1430         part('arch', my_arch, 'Config.lb', 0, 0)
1431
1432 def doconfigfile(path, confdir, file, rule):
1433         rname = os.path.join(confdir, file)
1434         loc.push(rname)
1435         fullpath = os.path.join(path, rname)
1436         fp = safe_open(fullpath, 'r')
1437         if (not parse(rule, fp.read())):
1438                 fatal("Could not parse file")
1439         exitiferrors()
1440         loc.pop()
1441
1442 #=============================================================================
1443 #               MISC FUNCTIONS
1444 #=============================================================================
1445 def ternary(val, yes, no):
1446         debug.info(debug.statement, "ternary %s" % expr)
1447         debug.info(debug.statement, "expr %s a %d yes %d no %d"% (expr, a, yes, no))
1448         if (val == 0):
1449                 debug.info(debug.statement, "Ternary returns %d" % yes)
1450                 return yes
1451         else:
1452                 debug.info(debug.statement, "Ternary returns %d" % no)
1453                 return no
1454
1455 def tohex(name):
1456         """atoi is in the python library, but not strtol? Weird!"""
1457         return eval('int(%s)' % name)
1458
1459 def IsInt(str):
1460         """ Is the given string an integer?"""
1461         try:
1462                 num = long(str)
1463                 return 1
1464         except ValueError:
1465                 return 0
1466
1467 def dequote(str):
1468         a = re.sub("^\"", "", str)
1469         a = re.sub("\"$", "", a)
1470         # highly un-intuitive, need four \!
1471         a = re.sub("\\\\\"", "\"", a)
1472         return a
1473
1474 def flatten_name(str):
1475         a = re.sub("[/-]", "_", str)
1476         return a
1477
1478 def topify(path):
1479         """If the first part of <path> matches treetop, replace 
1480         that part with $(TOP)"""
1481         if path[0:len(treetop)] == treetop:
1482                 path = path[len(treetop):len(path)]
1483                 if (path[0:1] == "/"):
1484                         path = path[1:len(path)]
1485                 path = "$(TOP)/" + path
1486         return path
1487
1488 %%
1489 # to make if work without 2 passses, we use an old hack from SIMD, the 
1490 # context bit. If the bit is 1, then ops get done, otherwise
1491 # ops don't get done. From the top level, context is always
1492 # 1. In an if, context depends on eval of the if condition
1493
1494 parser Config:
1495     ignore:                     r'\s+'
1496     ignore:                     "#.*?\r?\n"
1497
1498     # less general tokens should come first, otherwise they get matched
1499     # by the re's
1500     token ACTION:               'action'
1501     token ADDACTION:            'addaction'
1502     token ALWAYS:               'always'
1503     token ARCH:                 'arch'
1504     token BUILDROM:             'buildrom'
1505     token COMMENT:              'comment'
1506     token CONFIG:               'config'
1507     token CPU:                  'cpu'
1508     token CHIP:                 'chip'
1509     token DEFAULT:              'default'
1510     token DEFINE:               'define'
1511     token DEPENDS:              'depends'
1512     token DEVICE:               'device'
1513     token DIR:                  'dir'
1514     token DRIVER:               'driver'
1515     token DRQ:                  'drq'
1516     token ELSE:                 'else'
1517     token END:                  'end'
1518     token EOF:                  '$'
1519     token EQ:                   '='
1520     token EXPORT:               'export'
1521     token FORMAT:               'format'
1522     token IF:                   'if'
1523     token INIT:                 'init'
1524     token INITOBJECT:           'initobject'
1525     token INITINCLUDE:          'initinclude'
1526     token IO:                   'io'
1527     token IRQ:                  'irq'
1528     token LDSCRIPT:             'ldscript'
1529     token LOADOPTIONS:          'loadoptions'
1530     token MAINBOARD:            'mainboard'
1531     token MAINBOARDINIT:        'mainboardinit'
1532     token MAKEDEFINE:           'makedefine'
1533     token MAKERULE:             'makerule'
1534     token MEM:                  'mem'
1535     token NEVER:                'never'
1536     token NONE:                 'none'
1537     token NORTHBRIDGE:          'northbridge'
1538     token OBJECT:               'object'
1539     token OPTION:               'option'
1540     token PAYLOAD:              'payload'
1541     token PMC:                  'pmc'
1542     token PRINT:                'print'
1543     token REGISTER:             'register'
1544     token ROMIMAGE:             'romimage'
1545     token SOUTHBRIDGE:          'southbridge'
1546     token SUPERIO:              'superio'
1547     token TARGET:               'target'
1548     token USED:                 'used'
1549     token USES:                 'uses'
1550     token WRITE:                'write'
1551     token NUM:                  '[0-9]+'
1552     token HEX_NUM:              '[0-9a-fA-F]+'
1553     token HEX_PREFIX:           '0x'
1554     # Why is path separate? Because paths to resources have to at least
1555     # have a slash, we thinks
1556     token PATH:                 r'[-a-zA-Z0-9_.][-a-zA-Z0-9/_.]+[-a-zA-Z0-9_.]+'
1557     # Dir's on the other hand are abitrary
1558     # this may all be stupid.
1559     token DIRPATH:              r'[-a-zA-Z0-9_$()./]+'
1560     token ID:                   r'[a-zA-Z_.]+[a-zA-Z0-9_.]*'
1561     token DELEXPR:              r'{([^}]+|\\.)*}'
1562     token STR:                  r'"([^\\"]+|\\.)*"'
1563     token RAWTEXT:              r'.*'
1564     token ON:                   'on'
1565     token OFF:                  'off'
1566     token PCI:                  'pci'
1567     token PNP:                  'pnp'
1568     token I2C:                  'i2c'
1569     token APIC:                 'apic'
1570     token APIC_CLUSTER:         'apic_cluster'
1571     token PCI_DOMAIN:           'pci_domain'
1572     token LINK:                 'link'
1573
1574
1575     rule expr:          logical                 {{ l = logical }}
1576                         ( "&&" logical          {{ l = l and logical }}
1577                         | "||"  logical         {{ l = l or logical }}
1578                         )*                      {{ return l }}
1579
1580     rule logical:       factor                  {{ n = factor }}
1581                         ( "[+]" factor          {{ n = n+factor }}
1582                         | "-"  factor           {{ n = n-factor }}
1583                         )*                      {{ return n }}
1584
1585     rule factor:        term                    {{ v = term }}
1586                         ( "[*]" term            {{ v = v*term }}
1587                         | "/"  term             {{ v = v/term }}
1588                         | "<<"  term            {{ v = v << term }}
1589                         | ">=" term             {{ v = (v < term)}}
1590                         )*                      {{ return v }}
1591
1592     # A term is a number, variable, or an expression surrounded by parentheses
1593     rule term:          NUM                     {{ return long(NUM, 10) }}
1594                 |       HEX_PREFIX HEX_NUM      {{ return long(HEX_NUM, 16) }}
1595                 |       ID                      {{ return lookup(ID) }}
1596                 |       unop                    {{ return unop }}
1597                 |       "\\(" expr "\\)"        {{ return expr }}
1598
1599     rule unop:          "!" expr                {{ return not(expr) }}
1600
1601     rule partend<<C>>:  (stmt<<C>>)* END        {{ if (C): partpop()}}
1602
1603     # This is needed because the legacy cpu command could not distinguish
1604     # between cpu vendors. It should just be PATH, but getting this change
1605     # into the source tree will be tricky... 
1606     # DO NOT USE ID AS IT MAY GO AWAY IN THE FUTURE
1607     rule partid:        ID                      {{ return ID }}
1608                 |       PATH                    {{ return PATH }}
1609
1610     rule parttype:      NORTHBRIDGE             {{ return 'northbridge' }} 
1611                 |       SUPERIO                 {{ return 'superio' }}
1612                 |       PMC                     {{ return 'pmc' }}
1613                 |       SOUTHBRIDGE             {{ return 'southbridge' }}
1614                 |       CPU                     {{ return 'cpu' }}
1615                 |       CHIP                    {{ return '' }}
1616
1617     rule partdef<<C>>:                          {{ name = 0 }} {{ link = 0 }}
1618                         parttype partid         {{ if (parttype == 'cpu'): link = 1 }}
1619                         [ STR                   {{ name = dequote(STR) }}
1620                         ][ LINK NUM             {{ link = long(NUM, 10) }}
1621                         ]                       {{ if (C): part(parttype, partid, 'Config.lb', name, link) }}
1622                         partend<<C>>            
1623
1624     rule arch<<C>>:     ARCH ID                 {{ if (C): setarch(ID) }}
1625                         partend<<C>>
1626     
1627     rule mainboardinit<<C>>:
1628                         MAINBOARDINIT DIRPATH   {{ if (C): addcrt0include(DIRPATH)}}
1629
1630     rule initinclude<<C>>: 
1631                         INITINCLUDE 
1632                         STR 
1633                         DIRPATH                 {{ if (C): addinitinclude(STR, DIRPATH)}}
1634
1635     rule initobject<<C>>:
1636                         INITOBJECT DIRPATH      {{ if (C): addinitobject(DIRPATH)}}
1637
1638     rule object<<C>>:   OBJECT DIRPATH          {{ if (C): addobject(DIRPATH)}}
1639
1640     rule driver<<C>>:   DRIVER DIRPATH          {{ if (C): adddriver(DIRPATH)}}
1641
1642     rule dir<<C>>:      DIR DIRPATH             {{ if (C): dodir(DIRPATH, 'Config.lb') }}
1643
1644     rule default<<C>>:  DEFAULT ID EQ value     {{ if (C): setdefault(ID, value, 0) }}
1645
1646     rule ldscript<<C>>: LDSCRIPT DIRPATH        {{ if (C): addldscript(DIRPATH) }}
1647
1648     rule iif<<C>>:      IF ID                   {{ c = lookup(ID) }}
1649                         (stmt<<C and c>>)* 
1650                         [ ELSE (stmt<<C and not c>>)* ]
1651                         END
1652
1653     rule depsacts<<ID, C>>:
1654                         ( DEPENDS STR           {{ if (C): adddep(ID, STR) }}
1655                         | ACTION STR            {{ if (C): addaction(ID, STR) }}
1656                         )*
1657
1658     rule makerule<<C>>: MAKERULE DIRPATH        {{ if (C): addrule(DIRPATH) }} 
1659                         depsacts<<DIRPATH, C>> 
1660                         END
1661
1662     rule makedefine<<C>>:
1663                         MAKEDEFINE RAWTEXT      {{ if (C): adduserdefine(RAWTEXT) }}
1664
1665     rule addaction<<C>>:
1666                         ADDACTION ID STR        {{ if (C): addaction(ID, STR) }}
1667
1668     rule init<<C>>:     INIT DIRPATH            {{ if (C): addinit(DIRPATH) }}
1669
1670     rule field:         STR                     {{ return STR }}
1671
1672     rule register<<C>>: REGISTER field '=' STR  {{ if (C): addregister(field, STR) }}
1673
1674     rule enable<<C>>:                           {{ val = 1 }}
1675                         ( ON                    {{ val = 1 }}
1676                         | OFF                   {{ val = 0 }}
1677                         )                       {{ if(C): partstack.tos().set_enabled(val) }}
1678
1679     rule resource<<C>>:                         {{ type = "" }}
1680                         (  IO                   {{ type = "IORESOURCE_IO" }}
1681                         |   MEM                 {{ type = "IORESOURCE_MEM" }}
1682                         |   IRQ                 {{ type = "IORESOURCE_IRQ" }}
1683                         |   DRQ                 {{ type = "IORESOURCE_DRQ" }}
1684                         )
1685                         term '='                {{ index = term }}
1686                         term                    {{ value = term }}
1687                                                 {{ if (C): partstack.tos().add_resource(type, index, value) }}
1688     
1689                              
1690     rule resources<<C>>:                        {{ if (C): partstack.tos().start_resources() }}
1691                         ( resource<<C>> )*
1692                                                 {{ if (C): partstack.tos().end_resources() }}
1693             
1694     
1695     rule pci<<C>>:      PCI                     {{ if (C): devicepart('pci') }}
1696
1697                         HEX_NUM                 {{ slot = int(HEX_NUM,16) }}
1698                         '.' HEX_NUM             {{ function = int(HEX_NUM, 16) }}
1699                                                 {{ if (C): partstack.tos().addpcipath(slot, function) }}
1700     rule pci_domain<<C>>:       
1701                         PCI_DOMAIN              {{ if (C): devicepart('pci_domain') }}
1702                         HEX_NUM                 {{ pci_domain = int(HEX_NUM, 16) }}
1703                                                 {{ if (C): partstack.tos().addpci_domainpath(pci_domain) }}
1704
1705     rule pnp<<C>>:      PNP                     {{ if (C): devicepart('pnp') }}
1706                         HEX_NUM                 {{ port = int(HEX_NUM,16) }}
1707                         '.' HEX_NUM             {{ device = int(HEX_NUM, 16) }}
1708                                                 {{ if (C): partstack.tos().addpnppath(port, device) }}
1709                                                 
1710     rule i2c<<C>>:      I2C                     {{ if (C): devicepart('i2c') }}
1711                         HEX_NUM                 {{ device = int(HEX_NUM, 16) }}
1712                                                 {{ if (C): partstack.tos().addi2cpath(device) }}
1713
1714     rule apic<<C>>:     APIC                    {{ if (C): devicepart('apic') }}
1715                         HEX_NUM                 {{ apic_id = int(HEX_NUM, 16) }}
1716                                                 {{ if (C): partstack.tos().addapicpath(apic_id) }}
1717
1718     rule apic_cluster<<C>>: APIC_CLUSTER        {{ if (C): devicepart('apic_cluster') }}
1719                         HEX_NUM                 {{ cluster = int(HEX_NUM, 16) }}
1720                                                 {{ if (C): partstack.tos().addapicpath(cluster) }}
1721
1722     rule dev_path<<C>>:                         
1723                         pci<<C>>                {{ return pci }}
1724                 |       pci_domain<<C>>         {{ return pci_domain }}
1725                 |       pnp<<C>>                {{ return pnp }}
1726                 |       i2c<<C>>                {{ return i2c }}
1727                 |       apic<<C>>               {{ return apic }}
1728                 |       apic_cluster<<C>>       {{ return apic_cluster }}
1729                 
1730     rule prtval:        expr                    {{ return str(expr) }}
1731                 |       STR                     {{ return STR }}
1732
1733     rule prtlist:       prtval                  {{ el = "%(" + prtval }}
1734                         ( "," prtval            {{ el = el + "," + prtval }}
1735                         )*                      {{ return el + ")" }}   
1736
1737     rule prtstmt<<C>>:  PRINT STR               {{ val = STR }}
1738                         [ "," prtlist           {{ val = val + prtlist }}
1739                         ]                       {{ if (C): print eval(val) }}
1740
1741     rule config<<C>>:   CONFIG PATH             {{ if (C): addconfig(PATH) }}
1742
1743     rule device<<C>>:   DEVICE dev_path<<C>>
1744                         enable<<C>>                     
1745                         resources<<C>>
1746                         partend<<C>> 
1747
1748     rule stmt<<C>>:     arch<<C>>               {{ return arch}}
1749                 |       addaction<<C>>          {{ return addaction }}
1750                 |       config<<C>>             {{ return config}}
1751                 |       default<<C>>            {{ return default}}
1752                 |       dir<<C>>                {{ return dir}}
1753                 |       driver<<C>>             {{ return driver }}
1754                 |       iif<<C>>                {{ return iif }}
1755                 |       init<<C>>               {{ return init }}
1756                 |       initinclude<<C>>        {{ return initinclude }}
1757                 |       initobject<<C>>         {{ return initobject }}
1758                 |       ldscript<<C>>           {{ return ldscript}}
1759                 |       mainboardinit<<C>>      {{ return mainboardinit }}
1760                 |       makedefine<<C>>         {{ return makedefine }}
1761                 |       makerule<<C>>           {{ return makerule }}
1762                 |       object<<C>>             {{ return object }}
1763                 |       option<<C>>             {{ return option }}
1764                 |       partdef<<C>>            {{ return partdef }}
1765                 |       prtstmt<<C>>            {{ return prtstmt }}
1766                 |       register<<C>>           {{ return register }}
1767                 |       device<<C>>             {{ return device }}
1768
1769     # ENTRY for parsing Config.lb file
1770     rule cfgfile:       (uses<<1>>)* 
1771                         (stmt<<1>>)*
1772                         EOF                     {{ return 1 }}
1773
1774     rule cfgfile:       (uses<<1>>)* 
1775                         (stmt<<1>>)*
1776                         EOF                     {{ return 1 }}
1777
1778     rule usesid<<C>>:   ID                      {{ if (C): usesoption(ID) }}
1779
1780     rule uses<<C>>:     USES (usesid<<C>>)+
1781
1782     rule mainboardvariables:    (uses<<1>>)*
1783                                 (default<<1>>)*
1784                                 (option<<1>>)*
1785                                 END             {{ return 1}}
1786
1787     rule value:         STR                     {{ return dequote(STR) }} 
1788                 |       expr                    {{ return expr }}
1789                 |       DELEXPR                 {{ return DELEXPR }}
1790
1791     rule option<<C>>:   OPTION ID EQ value      {{ if (C): setoption(ID, value, 0) }}
1792
1793     rule opif<<C>>:     IF ID                   {{ c = lookup(ID) }}
1794                         (opstmt<<C and c>>)* 
1795                         [ ELSE (opstmt<<C and not c>>)* ] 
1796                         END
1797
1798     rule opstmt<<C>>:   option<<C>>
1799                 |       opif<<C>>
1800                 |       prtstmt<<C>>
1801
1802     rule payload<<C>>:  PAYLOAD DIRPATH         {{ if (C): payload(DIRPATH) }}
1803
1804     rule mainboard:
1805                         MAINBOARD PATH          {{ mainboardsetup(PATH) }}
1806
1807     rule romif<<C>>:    IF ID                   {{ c = lookup(ID) }}
1808                         (romstmt<<C and c>>)* 
1809                         [ ELSE (romstmt<<C and not c>>)* ]
1810                         END
1811
1812     rule romstmt<<C>>:  romif<<C>>
1813                 |       option<<C>>
1814                 |       payload<<C>>
1815
1816     rule romimage:      ROMIMAGE STR            {{ startromimage(dequote(STR)) }}
1817                         (romstmt<<1>>)*
1818                         END                     {{ endromimage() }}
1819
1820     rule roms:          STR                     {{ s = '[' + STR }}
1821                         ( STR                   {{ s = s + "," + STR }}
1822                         )*                      {{ return eval(s + ']') }}
1823
1824     rule buildrom:      BUILDROM DIRPATH expr roms      {{ addbuildrom(DIRPATH, expr, roms) }}
1825
1826     rule romstmts:      romimage 
1827                 |       buildrom
1828                 |       opstmt<<1>>
1829
1830     # ENTRY for parsing root part
1831     rule board:         {{ loadoptions("config", "Options.lb", "options") }}
1832                         TARGET DIRPATH          {{ target(DIRPATH) }}
1833                         mainboard
1834                         (romstmts)*             
1835                         EOF                     {{ return 1 }}
1836
1837     # ENTRY for parsing a delayed value
1838     rule delexpr:       "{" expr "}" EOF        {{ return expr }}
1839
1840     rule wrstr<<ID>>:   STR                     {{ setwrite(ID, dequote(STR)) }}
1841
1842     rule defstmts<<ID>>:                        {{ d = 0 }}
1843                         ( DEFAULT
1844                           ( value               {{ setdefault(ID, value, 1) }}
1845                           | NONE                {{ setnodefault(ID) }}
1846                           )                     {{ d = d | 1 }}
1847                         | FORMAT STR            {{ setformat(ID, dequote(STR)) }}
1848                         | EXPORT 
1849                           ( ALWAYS              {{ setexported(ID) }}
1850                           | USED                {{ setexportable(ID) }}
1851                           | NEVER               {{ setnoexport(ID) }}
1852                           )                     {{ d = d | 2 }}
1853                         | COMMENT STR           {{ setcomment(ID, dequote(STR)); d = d | 4 }}
1854                         | WRITE (wrstr<<ID>>)+
1855                         )+                      {{ return d }}
1856                 
1857     rule define:        DEFINE ID               {{ newoption(ID) }}
1858                         defstmts<<ID>> END      {{ validdef(ID, defstmts) }}
1859
1860     # ENTRY for parsing Options.lb file
1861     rule options:       (define)* EOF           {{ return 1 }}
1862 %%
1863
1864 #=============================================================================
1865 #               FILE OUTPUT 
1866 #=============================================================================
1867 def writemakefileheader(file, fname):
1868         file.write("# File: %s\n" % fname)
1869         file.write("# This file was generated by '%s %s %s'\n\n"
1870                 % (sys.argv[0], sys.argv[1], sys.argv[2]))
1871
1872 def writemakefilesettings(path):
1873         """ Write Makefile.settings to seperate the settings
1874         from the actual makefile creation."""
1875
1876         global treetop, target_dir
1877
1878         filename = os.path.join(path, "Makefile.settings")
1879         print "Creating", filename
1880         file = safe_open(filename, 'w+')
1881         writemakefileheader(file, filename)
1882         file.write("TOP:=%s\n" % (treetop))
1883         file.write("TARGET_DIR:=%s\n" % target_dir)
1884         file.close()
1885
1886 def writeimagesettings(image):
1887         """Write Makefile.settings to seperate the settings
1888         from the actual makefile creation."""
1889
1890         global treetop
1891         global global_options_by_order
1892
1893         filename = os.path.join(image.gettargetdir(), "Makefile.settings")
1894         print "Creating", filename
1895         file = safe_open(filename, 'w+')
1896         writemakefileheader(file, filename)
1897         file.write("TOP:=%s\n" % (treetop))
1898         file.write("TARGET_DIR:=%s\n" % (image.gettargetdir()))
1899         file.write("\n")
1900         exported = []
1901         for o in global_exported_options:
1902                 exported.append(o)
1903         for o in image.exported_options:
1904                 if (not o in exported):
1905                         exported.append(o)
1906         for o in exported:
1907                 file.write("export %s:=" % o.name)
1908                 if (hasvalue(o.name, image)):
1909                         file.write("%s" % getformated(o.name, image))
1910                 file.write("\n")
1911         file.write("\n")
1912         file.write("export VARIABLES :=\n")
1913         for o in exported:
1914                 file.write("export VARIABLES += %s\n" % o.name)
1915         file.write("\n")
1916         file.close()
1917
1918 # write the romimage makefile
1919 # let's try the Makefile
1920 # first, dump all the -D stuff
1921
1922 def writeimagemakefile(image):
1923         makefilepath = os.path.join(image.gettargetdir(), "Makefile")
1924         print "Creating", makefilepath
1925         file = safe_open(makefilepath, 'w+')
1926         writemakefileheader(file, makefilepath)
1927
1928         #file.write("include cpuflags\n")
1929         # Putting "include cpuflags" in the Makefile has the problem that the
1930         # cpuflags file would be generated _after_ we want to include it.
1931         # Instead, let make do the work of computing CPUFLAGS:
1932         file.write("# Get the value of TOP, VARIABLES, and several other variables.\n")
1933         file.write("include Makefile.settings\n\n")
1934         file.write("# Function to create an item like -Di586 or -DCONFIG_MAX_CPUS='1' or -Ui686\n")
1935         file.write("D_item = $(if $(subst undefined,,$(origin $1)),-D$1$(if $($1),='$($1)',),-U$1)\n\n")
1936         file.write("# Compute the value of CPUFLAGS here during make's first pass.\n")
1937         file.write("CPUFLAGS := $(foreach _var_,$(VARIABLES),$(call D_item,$(_var_)))\n\n")
1938
1939         for i in image.getuserdefines():
1940                 file.write("%s\n" %i)
1941         file.write("\n")
1942
1943         # main rule
1944         file.write("all: linuxbios.rom")
1945         # print out all the object dependencies
1946         file.write("\n# object dependencies (objectrules:)\n")
1947         file.write("INIT-OBJECTS :=\n")
1948         file.write("OBJECTS :=\n")
1949         file.write("DRIVER :=\n")
1950         file.write("\nSOURCES :=\n")
1951         for irule, init in image.getinitobjectrules().items():
1952                 i_name = init[0]
1953                 i_source = init[1]
1954                 file.write("INIT-OBJECTS += %s\n" % (i_name))
1955                 file.write("SOURCES += %s\n" % (i_source))
1956
1957         for objrule, obj in image.getobjectrules().items():
1958                 obj_name = obj[0]
1959                 obj_source = obj[1]
1960                 file.write("OBJECTS += %s\n" % (obj_name))
1961                 file.write("SOURCES += %s\n" % (obj_source))
1962
1963         # for chip_target.c
1964         file.write("OBJECTS += static.o\n")
1965         file.write("SOURCES += static.c\n")
1966
1967         for driverrule, driver in image.getdriverrules().items():
1968                 obj_name = driver[0]
1969                 obj_source = driver[1]
1970                 file.write("DRIVER += %s\n" % (obj_name))
1971                 file.write("SOURCES += %s\n" % (obj_source))
1972
1973         # Print out all ldscript.ld dependencies.
1974         file.write("\n# ldscript.ld dependencies:\n")
1975         file.write("LDSUBSCRIPTS-1 := \n" )
1976         for script in image.getldscripts():
1977                 file.write("LDSUBSCRIPTS-1 += %s\n" % topify(script))
1978
1979         # Print out the dependencies for crt0_includes.h
1980         file.write("\n# Dependencies for crt0_includes.h\n")
1981         file.write("CRT0_INCLUDES:=\n")
1982         for inc in image.getinitincludes():
1983                 if (local_path.match(inc)):
1984                         file.write("CRT0_INCLUDES += %s\n" % inc)
1985                 else:
1986                         file.write("CRT0_INCLUDES += $(TOP)/src/%s\n" % inc)
1987
1988         # Print out the user defines.
1989         file.write("\n# userdefines:\n")
1990                 
1991         # Print out the base rules.
1992         # Need to have a rule that counts on 'all'.
1993         file.write("\n# mainrulelist:")
1994
1995         # Print out any user rules.
1996         file.write("\n# From makerule or docipl commands:\n")
1997
1998         file.write("\n# initobjectrules:\n")
1999         for irule, init in image.getinitobjectrules().items():
2000                 source = topify(init[1])
2001                 type = init[2]
2002                 if (type  == 'S'):
2003                         # for .S, .o depends on .s
2004                         file.write("%s: %s.s\n" % (init[0], init[3]))
2005                         file.write("\t@echo $(CC) ... -o $@ $<\n")
2006                         file.write("\t$(CC) -c $(CPU_OPT) -o $@ $<\n")
2007                         # and .s depends on .S
2008                         file.write("%s.s: %s\n" % (init[3], source))
2009                         file.write("\t@echo $(CPP) ... $< > $@\n")
2010                         # Note: next 2 lines are ONE output line!
2011                         file.write("\t$(CPP) $(CPPFLAGS) $< ")
2012                         file.write(">$@.new && mv $@.new $@\n")
2013                 else:
2014                         file.write("%s: %s\n" % (init[0], source))
2015                         file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
2016
2017         file.write("\n# objectrules:\n")
2018         for objrule, obj in image.getobjectrules().items():
2019                 source = topify(obj[1])
2020                 type = obj[2]
2021                 if (type  == 'S'):
2022                         # for .S, .o depends on .s
2023                         file.write("%s: %s.s\n" % (obj[0], obj[3]))
2024                         file.write("\t@echo $(CC) ... -o $@ $<\n")
2025                         file.write("\t$(CC) -c $(CPU_OPT) -o $@ $<\n")
2026                         # and .s depends on .S
2027                         file.write("%s.s: %s\n" % (obj[3], source))
2028                         file.write("\t@echo $(CPP) ... $< > $@\n")
2029                         # Note: next 2 lines are ONE output line!
2030                         file.write("\t$(CPP) $(CPPFLAGS) $< ")
2031                         file.write(">$@.new && mv $@.new $@\n")
2032                 else:
2033                         file.write("%s: %s\n" % (obj[0], source))
2034                         file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
2035                 #file.write("%s\n" % objrule[2])
2036
2037         for driverrule, driver in image.getdriverrules().items():
2038                 source = topify(driver[1])
2039                 file.write("%s: %s\n" % (driver[0], source))
2040                 file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
2041                 #file.write("%s\n" % objrule[2])
2042
2043         # special rule for chip_target.c
2044         file.write("static.o: static.c\n")
2045         file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
2046
2047         # Print out the rules that will make cause the files
2048         # generated by NLBConfig.py to be remade if any dependencies change.
2049
2050         file.write("\n# Remember the automatically generated files\n")
2051         file.write("GENERATED:=\n")
2052         for genfile in ['Makefile',
2053                         'nsuperio.c',
2054                         'static.c',
2055                         'LinuxBIOSDoc.config' ]:
2056                 file.write("GENERATED += %s\n" % genfile)
2057         file.write("GENERATED += %s\n" % image.getincludefilename())
2058
2059         keys = global_options_by_order
2060         keys.sort()
2061         file.write("\necho:\n")
2062         for key in keys:
2063                  file.write("\t@echo %s='$(%s)'\n"% (key,key))
2064
2065         for i, m in image.getmakerules().items():
2066                 file.write("%s: " %i)
2067                 for i in m.dependency:
2068                         file.write("%s " % i)
2069                 file.write("\n")
2070                 for i in m.actions:
2071                         file.write("\t%s\n" % i)
2072         file.close()
2073
2074 #
2075 def writemakefile(path):
2076         makefilepath = os.path.join(path, "Makefile")
2077         print "Creating", makefilepath
2078         file = safe_open(makefilepath, 'w+')
2079         writemakefileheader(file, makefilepath)
2080         file.write("include Makefile.settings\n\n")
2081
2082         # main rule
2083         file.write("all: ")
2084         for i in romimages.keys():
2085                 file.write("%s-rom " % i)
2086         file.write("buildroms\n\n")
2087         for i, o in romimages.items():
2088                 file.write("%s-rom:\n" % o.getname())
2089                 file.write("\tif (cd %s; \\\n" % o.getname())
2090                 file.write("\t\tmake linuxbios.rom)\\\n")
2091                 file.write("\tthen true; else exit 1; fi;\n\n")
2092         file.write("clean: ")
2093         for i in romimages.keys():
2094                 file.write("%s-clean " % i)
2095         file.write("\n\n")
2096         for i, o in romimages.items():
2097                 file.write("%s-clean:\n" % o.getname())
2098                 file.write("\t(cd %s; make clean)\n" % o.getname())
2099         
2100         file.write("\nbuildroms:\n")
2101         for i in buildroms:
2102                 file.write("\tcat ")
2103                 for j in i.roms:
2104                         file.write("%s/linuxbios.rom " % j )
2105                 file.write("> %s\n" % i.name)
2106         file.write("\n")
2107         
2108         file.close()
2109
2110 def writeinitincludes(image):
2111         global include_pattern
2112         filepath = os.path.join(image.gettargetdir(), image.getincludefilename())
2113         print "Creating", filepath
2114         outfile = safe_open(filepath, 'w+')
2115         if (image.newformat()):
2116                 infile = safe_open(image.getinitfile(), 'r')
2117
2118                 line = infile.readline()
2119                 while (line):
2120                         p = include_pattern.match(line)
2121                         if (p):
2122                                 for i in image.getinitincludes():
2123                                         inc = image.getinitinclude(i)
2124                                         if (inc.getstring() == p.group(1)):
2125                                                 outfile.write("#include \"%s\"\n" % inc.getpath())
2126                         else:
2127                                 outfile.write(line)
2128                         line = infile.readline()
2129
2130                 infile.close()
2131         else:
2132                 for i in image.getinitincludes():
2133                         outfile.write("#include <%s>\n" % i)
2134         outfile.close()
2135
2136 def writeldoptions(image):
2137         """Write ldoptions file."""
2138         filename = os.path.join(image.gettargetdir(), "ldoptions")
2139         print "Creating", filename
2140         file = safe_open(filename, 'w+')
2141         for o in global_exported_options:
2142                 if (hasvalue(o.name, image) and IsInt(getoption(o.name, image))):
2143                         file.write("%s = %s;\n" % (o.name, getformated(o.name, image)))
2144         for o in image.exported_options:
2145                 if (not o in global_exported_options and hasvalue(o.name, image) and IsInt(getoption(o.name, image))):
2146                         file.write("%s = %s;\n" % (o.name, getformated(o.name, image)))
2147         file.close()
2148
2149 def dumptree(part, lvl):
2150         debug.info(debug.dumptree, "DUMPTREE ME is")
2151         part.dumpme(lvl)
2152         # dump the siblings -- actually are there any? not sure
2153         # siblings are:
2154         debug.info(debug.dumptree, "DUMPTREE SIBLINGS are")
2155         kid = part.siblings
2156         while (kid):
2157                 kid.dumpme(lvl)
2158                 kid = kid.siblings
2159         # dump the kids
2160         debug.info(debug.dumptree, "DUMPTREE KIDS are")
2161         #for kid in part.children:
2162         if (part.children):
2163                 dumptree(part.children, lvl+1)
2164         debug.info(debug.dumptree, "DONE DUMPTREE")
2165
2166 def writecode(image):
2167         filename = os.path.join(img_dir, "static.c")
2168         print "Creating", filename
2169         file = safe_open(filename, 'w+')
2170         file.write("#include <device/chip.h>\n")
2171         file.write("#include <device/pci.h>\n")
2172         for path in image.getconfigincludes().values():
2173                 file.write("#include \"%s\"\n" % path)
2174         gencode(image.getroot(), file, 0)
2175         gencode(image.getroot(), file, 1)
2176         file.close()
2177
2178 def gencode(part, file, pass_num):
2179         debug.info(debug.gencode, "GENCODE ME is")
2180         part.gencode(file, pass_num)
2181         # dump the siblings -- actually are there any? not sure
2182         debug.info(debug.gencode, "GENCODE SIBLINGS are")
2183         kid = part.siblings
2184         while (kid):
2185                 kid.gencode(file, pass_num)
2186                 kid = kid.siblings
2187         # now dump the children 
2188         debug.info(debug.gencode, "GENCODE KIDS are")
2189         if (part.children):
2190                 gencode(part.children, file, pass_num)
2191         kid = part.siblings
2192         while (kid):
2193                 if (kid.children):
2194                         gencode(kid.children, file, pass_num)
2195                 kid = kid.siblings
2196         debug.info(debug.gencode, "DONE GENCODE")
2197
2198 def verifyparse():
2199         """Add any run-time checks to verify that parsing the configuration
2200         was successful"""
2201
2202         for image in romimages.values():
2203                 print("Verifying ROMIMAGE %s" % image.name)
2204                 if (image.newformat() and image.getinitfile() == ''):
2205                         fatal("An init file must be specified")
2206                 for op in image.exported_options:
2207                         if (getoptionvalue(op.name, op, image) == 0 and getoptionvalue(op.name, op, 0) == 0):
2208                                 warning("Exported option %s has no value (check Options.lb)" % op.name);
2209         print("Verifing global options")
2210         for op in global_exported_options:
2211                 if (getoptionvalue(op.name, op, 0) == 0):
2212                         notice("Exported option %s has no value (check Options.lb)" % op.name);
2213                         
2214 #=============================================================================
2215 #               MAIN PROGRAM
2216 #=============================================================================
2217 if __name__=='__main__':
2218         from sys import argv
2219         if (len(argv) < 3):
2220                 fatal("Args: <file> <path to linuxbios>")
2221
2222         top_config_file = os.path.abspath(sys.argv[1])
2223
2224         treetop = os.path.abspath(sys.argv[2])
2225
2226         # Now read in the customizing script...
2227         loc.push(argv[1])
2228         fp = safe_open(argv[1], 'r')
2229         if (not parse('board', fp.read())):
2230                 fatal("Could not parse file")
2231         loc.pop()
2232
2233         verifyparse()
2234
2235         # no longer need to check if an options has been used
2236         alloptions = 1
2237
2238         for image_name, image in romimages.items():
2239                 if (debug.level(debug.dumptree)):
2240                         debug.info(debug.dumptree, "DEVICE TREE:")
2241                         dumptree(image.getroot(), 0)
2242
2243                 img_dir = image.gettargetdir()
2244                 if not os.path.isdir(img_dir):
2245                         print "Creating directory %s" % img_dir
2246                         os.makedirs(img_dir)
2247
2248                 if (debug.level(debug.dump)):
2249                         for i in image.getinitincludes():
2250                                 debug.info(debug.dump, "crt0include file %s" % i)
2251                         for i in image.getdriverrules().keys():
2252                                 debug.info(debug.dump, "driver file %s" % i)
2253                         for i in image.getldscripts():
2254                                 debug.info(debug.dump, "ldscript file %s" % i)
2255                         for i, m in image.getmakerules().items():
2256                                 debug.info(debug.dump, " makerule %s dep %s act %s" % (i, m.dependency, m.actions))
2257
2258                 writecode(image)
2259                 writeimagesettings(image)
2260                 writeinitincludes(image)
2261                 writeimagemakefile(image)
2262                 writeldoptions(image)
2263
2264         writemakefilesettings(target_dir)
2265         writemakefile(target_dir)
2266
2267         sys.exit(0)