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