- Put the rule for the Makefile at the bottom of the makefile!
[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 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 a pci_domain number 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 usesoption(self, name):
955                 """Declare option that can be used by this part"""
956                 global global_options
957                 o = getdict(global_options, name)
958                 if (o == 0):
959                         fatal("can't use undefined option %s" % name)
960                 o1 = getdict(self.uses_options, name)
961                 if (o1):
962                         return
963                 setdict(self.uses_options, name, o)
964                 exportoption(o, self.image.exported_options)
965
966 # -----------------------------------------------------------------------------
967 #                    statements 
968 # -----------------------------------------------------------------------------
969
970 def getdict(dict, name):
971         if name not in dict.keys(): 
972                 debug.info(debug.dict, "Undefined: %s" % name)
973                 return 0
974         v = dict.get(name, 0)
975         debug.info(debug.dict, "getdict %s returning %s" % (name, v))
976         return v
977
978 def setdict(dict, name, value):
979         debug.info(debug.dict, "setdict sets %s to %s" % (name, value))
980         dict[name] = value
981
982 # options. 
983 # to create an option, it has to not exist. 
984 # When an option value is fetched, the fact that it was used is 
985 # remembered. 
986 # Legal things to do:
987 # set a default value, then set a real value before the option is used.
988 # set a value, try to set a default, default silently fails.
989 # Illegal:
990 # use the value, then try to set the value
991
992 def newoption(name):
993         global global_options, global_options_by_order
994         o = getdict(global_options, name)
995         if (o):
996                 fatal("option %s already defined" % name)
997         o = option(name)
998         setdict(global_options, name, o)
999         global_options_by_order.append(name)
1000
1001 def newoptionvalue(name, image):
1002         g = getdict(global_option_values, name)
1003         v = option_value(name, g)
1004         if (image):
1005                 setdict(image.getvalues(), name, v)
1006         else:
1007                 setdict(global_option_values, name, v)
1008         return v
1009
1010 def getoptionvalue(name, op, image):
1011         global global_option_values
1012         #print "getoptionvalue name %s op %s image %s\n" % (name, op,image)
1013         if (op == 0):
1014                 print_stack()
1015                 fatal("Option %s undefined (missing use command?)" % name)
1016         if (image):
1017                 v = getdict(image.getvalues(), name)
1018         else:
1019                 v = getdict(global_option_values, name)
1020         return v
1021
1022 def getoption(name, image):
1023         """option must be declared before being used in a part
1024         if we're not processing a part, then we must
1025         be at the top level where all options are available"""
1026
1027         global global_uses_options, alloptions, curimage
1028
1029         #print "getoption: name %s image %s alloptions %s curimage %s\n\n" % (name, image, alloptions, curimage)
1030         curpart = partstack.tos()
1031         if (alloptions):
1032                 o = getdict(global_options, name)
1033         elif (curpart):
1034                 o = getdict(curpart.uses_options, name)
1035                 if (o == 0):
1036                         print "curpart.uses_optins is %s\n" % curpart.uses_options
1037         else:
1038                 o = getdict(global_uses_options, name)
1039         v = getoptionvalue(name, o, image)
1040         if (v == 0):
1041                 v = getoptionvalue(name, o, 0)
1042         if (v == 0):
1043                 fatal("No value for option %s" % name)
1044         val = v.contents()
1045         if (not (type(val) is types.StringType)):
1046                 return v.contents()
1047         if (val == '' or val[0] != '{'):
1048                 return v.contents()
1049         s = curimage
1050         curimage = image
1051         val = parse('delexpr', val)
1052         curimage = s
1053         exitiferrors()
1054         return val
1055
1056 def setoption(name, value, imp):
1057         """Set an option from within a configuration file. Normally this
1058         is only permitted in the target (top level) configuration file.
1059         If 'imp' is true, then set an option implicitly (e.g. 'arch' 
1060         and 'mainboard' statements). Implicit options can be set anywhere 
1061         the statements are legal, but also performs an implicit 'uses' 
1062         for the option"""
1063
1064         global loc, global_options, global_option_values, curimage
1065
1066         curpart = partstack.tos()
1067         if (not imp and curpart):
1068                 fatal("Options may only be set in target configuration file")
1069         if (imp):
1070                 usesoption(name)
1071         if (curpart):
1072                 o = getdict(curpart.uses_options, name)
1073         else:
1074                 o = getdict(global_uses_options, name)
1075         if (not o):
1076                 fatal("Attempt to set nonexistent option %s (missing USES?)" % name)
1077         v = getoptionvalue(name, o, curimage)
1078         if (v == 0):
1079                 v = newoptionvalue(name, curimage)
1080         v.setvalue(value)
1081
1082 def exportoption(op, exported_options):
1083         if (not op.isexportable()):
1084                 return
1085         if (not op in exported_options):
1086                 exported_options.append(op)
1087
1088 def setdefault(name, value, isdef):
1089         """Set the default value of an option from within a configuration 
1090         file. This is permitted from any configuration file, but will
1091         result in a warning if the default is set more than once.
1092         If 'isdef' is set, we're defining the option in Options.lb so
1093         there is no need for 'uses'."""
1094
1095         global loc, global_options, curimage
1096
1097         if (isdef):
1098                 o = getdict(global_options, name)
1099                 if (not o):
1100                         return
1101                 image = 0
1102         else:
1103                 curpart = partstack.tos()
1104                 if (curpart):
1105                         o = getdict(curpart.uses_options, name)
1106                 else:
1107                         o = getdict(global_uses_options, name)
1108                 if (not o):
1109                         fatal("Attempt to set default for nonexistent option %s (missing USES?)" % name)
1110                 image = curimage
1111
1112         v = getoptionvalue(name, o, image)
1113         if (v == 0):
1114                 v = newoptionvalue(name, image)
1115         v.setdefault(value)
1116
1117 def setnodefault(name):
1118         global loc, global_options
1119         o = getdict(global_options, name)
1120         if (not o):
1121                 return
1122         v = getdict(global_option_values, name)
1123         if (v != 0):
1124                 warning("removing default for %s" % name)
1125                 del global_option_values[name]
1126
1127 def setcomment(name, value):
1128         global loc, global_options
1129         o = getdict(global_options, name)
1130         if (not o):
1131                 fatal("setcomment: %s not here" % name)
1132         o.setcomment(value, loc)
1133
1134 def setexported(name):
1135         global global_options
1136         o = getdict(global_options, name)
1137         if (not o):
1138                 fatal("setexported: %s not here" % name)
1139         o.setexportable()
1140         global_exported_options.append(o)
1141
1142 def setnoexport(name):
1143         global global_options
1144         o = getdict(global_options, name)
1145         if (not o):
1146                 fatal("setnoexport: %s not here" % name)
1147         o.setnoexport()
1148         if (o in global_exported_options):
1149                 global_exported_options.remove(o)
1150
1151 def setexportable(name):
1152         global global_options
1153         o = getdict(global_options, name)
1154         if (not o):
1155                 fatal("setexportable: %s not here" % name)
1156         o.setexportable()
1157
1158 def setformat(name, fmt):
1159         global global_options
1160         o = getdict(global_options, name)
1161         if (not o):
1162                 fatal("setformat: %s not here" % name)
1163         o.setformat(fmt)
1164
1165 def getformated(name, image):
1166         global global_options, global_option_values
1167         o = getdict(global_options, name)
1168         v = getoption(name, image)
1169         f = o.getformat()
1170         return (f % v)
1171
1172 def setwrite(name, part):
1173         global global_options
1174         o = getdict(global_options, name)
1175         if (not o):
1176                 fatal("setwrite: %s not here" % name)
1177         o.setwrite(part)
1178
1179 def hasvalue(name, image):
1180         global global_options
1181         o = getdict(global_options, name)
1182         if (o == 0):
1183                 return 0
1184         v = 0
1185         if (image):
1186                 v = getdict(image.getvalues(), name)
1187         if (v == 0):
1188                 v = getdict(global_option_values, name)
1189         return (v != 0)
1190
1191 def isset(name, part):
1192         global global_uses_options, global_option_values, curimage
1193         if (part):
1194                 o = getdict(part.uses_options, name)
1195         else:
1196                 o = getdict(global_uses_options, name)
1197         if (o == 0):
1198                 return 0
1199         v = 0
1200         if (curimage):
1201                 v = getdict(curimage.getvalues(), name)
1202         if (v == 0):
1203                 v = getdict(global_option_values, name)
1204         return (v != 0 and v.isset())
1205
1206 def usesoption(name):
1207         global global_options, global_uses_options
1208         curpart = partstack.tos()
1209         if (curpart):
1210                 curpart.usesoption(name)
1211                 return
1212         o = getdict(global_options, name)
1213         if (o == 0):
1214                 fatal("Can't use undefined option %s" % name)
1215         o1 = getdict(global_uses_options, name)
1216         if (o1):
1217                 return
1218         setdict(global_uses_options, name, o)
1219         exportoption(o, global_exported_options)
1220
1221 def validdef(name, defval):
1222         global global_options
1223         o = getdict(global_options, name)
1224         if (not o):
1225                 fatal("validdef: %s not here" % name)
1226         if ((defval & 1) != 1):
1227             fatal("Must specify default value for option %s" % name)
1228         if ((defval & 2) != 2):
1229             fatal("Must specify export for option %s" % name)
1230         if ((defval & 4) != 4):
1231             fatal("Must specify comment for option %s" % name)
1232
1233 def loadoptions(path, file, rule):
1234         file = os.path.join('src', path, file)
1235         optionsfile = os.path.join(treetop, file)
1236         fp = safe_open(optionsfile, 'r')
1237         loc.push(file)
1238         if (not parse(rule, fp.read())):
1239                 fatal("Could not parse file")
1240         loc.pop()
1241
1242 def addinit(path):
1243         global curimage, dirstack
1244         if (path[0] == '/'):
1245                 curimage.setinitfile(treetop + '/src/' + path)
1246         else:
1247                 curimage.setinitfile(dirstack.tos() + '/' + path)
1248         print "Adding init file: %s" % path
1249
1250 def addconfig(path):
1251         global partstack
1252         curpart = partstack.tos()
1253         curpart.addconfig(path)
1254
1255 def addregister(field, value):
1256         global partstack
1257         curpart = partstack.tos()
1258         curpart.addregister(field, value)
1259
1260 def addcrt0include(path):
1261         """we do the crt0include as a dictionary, so that if needed we
1262         can trace who added what when. Also it makes the keys
1263         nice and unique."""
1264         global curimage
1265         curimage.addinitinclude(0, path)
1266
1267 def addinitinclude(str, path):
1268         global curimage
1269         curimage.addinitinclude(dequote(str), path)
1270
1271 def addldscript(path):
1272         global curimage, dirstack
1273         curdir = dirstack.tos()
1274         if (path[0] == '/'):
1275                 fullpath =  treetop + '/src/' + path
1276         else:
1277                 fullpath = curdir + '/' + path
1278         debug.info(debug.statement, "fullpath :%s: curdir :%s: path :%s:" % (fullpath, curdir, path))
1279         curimage.addldscript(fullpath)
1280
1281 def payload(path):
1282         global curimage
1283         curimage.setpayload(path)
1284         adduserdefine("PAYLOAD:=%s"%path)
1285
1286 def startromimage(name):
1287         global romimages, curimage, target_dir, target_name
1288         curpart = partstack.tos()
1289         print "Configuring ROMIMAGE %s Curimage %s" % (name, curimage)
1290         print "Curpart is %s\n" % curpart
1291         o = getdict(romimages, name)
1292         if (o):
1293                 fatal("romimage %s previously defined" % name)
1294         curimage = romimage(name)
1295         curimage.settargetdir(os.path.join(target_dir, name))
1296         #o = partobj(curimage, target_dir, 0, 'board', target_name)
1297         #curimage.setroot(o)
1298         setdict(romimages, name, curimage)
1299         dodir('/config', 'Config.lb')
1300
1301 def endromimage():
1302         global curimage
1303         mainboard()
1304         print "End ROMIMAGE"
1305         curimage = 0
1306         #curpart = 0
1307
1308 def mainboardsetup(path):
1309         global full_mainboard_path, mainboard_path
1310         mainboard_path = os.path.join('mainboard', path)
1311         loadoptions(mainboard_path, 'Options.lb', 'mainboardvariables')
1312         full_mainboard_path = os.path.join(treetop, 'src', 'mainboard', path)
1313         vendor = re.sub("/.*", "", path)
1314         part_number = re.sub("[^/]*/", "", path)
1315         setdefault('MAINBOARD', full_mainboard_path, 0)
1316         setdefault('MAINBOARD_VENDOR', vendor, 0)
1317         setdefault('MAINBOARD_PART_NUMBER', part_number, 0)
1318
1319 def mainboard():
1320         global curimage, dirstack, partstack
1321         file = 'Config.lb'
1322         partdir = mainboard_path
1323         srcdir = os.path.join(treetop, 'src')
1324         fulldir = os.path.join(srcdir, partdir)
1325         type_name = flatten_name(partdir)
1326         newpart = partobj(curimage, fulldir, partstack.tos(), 'mainboard', \
1327                 type_name, 0, 'chip')
1328         #print "Configuring PART %s" % (type)
1329         partstack.push(newpart)
1330         #print "  new PART tos is now %s\n" %partstack.tos().info()
1331         dirstack.push(fulldir)
1332         loadoptions(mainboard_path, 'Options.lb', 'mainboardvariables')
1333         # special case for 'cpu' parts.
1334         # we could add a new function too, but this is rather trivial.
1335         # if the part is a cpu, and we haven't seen it before,
1336         # arrange to source the directory /cpu/'type'
1337         doconfigfile(srcdir, partdir, file, 'cfgfile')
1338         curimage.setroot(partstack.tos())
1339         partpop()
1340
1341 def addbuildrom(filename, size, roms):
1342         global buildroms
1343         print "Build ROM size %d" % size
1344         b = buildrom(filename, size, roms)
1345         buildroms.append(b)
1346
1347 def addinitobject(object_name):
1348         global curimage
1349         curimage.addinitobjectrule(object_name)
1350
1351 def addobject(object_name):
1352         global curimage
1353         curimage.addobjectrule(object_name)
1354
1355 def adddriver(driver_name):
1356         global curimage
1357         curimage.adddriverrule(driver_name)
1358
1359 def target(name):
1360         global target_dir, target_name
1361         print "Configuring TARGET %s" % name
1362         target_name = name
1363         target_dir = os.path.join(os.path.dirname(loc.file()), name)
1364         if not os.path.isdir(target_dir):
1365                 print "Creating directory %s" % target_dir
1366                 os.makedirs(target_dir)
1367         print "Will place Makefile, crt0.S, etc. in %s" % target_dir
1368
1369
1370 def cpudir(path):
1371         global cpu_type
1372         if (cpu_type and (cpu_type != path)):
1373                 fatal("Two different CPU types: %s and %s" % (cpu_type, path))
1374         srcdir = "/cpu/%s" % path
1375         dodir(srcdir, "Config.lb")
1376         cpu_type = path
1377         
1378 def devicepart(type):
1379         global curimage, dirstack, partstack
1380         newpart = partobj(curimage, 0, partstack.tos(), type, \
1381                         '', 0, 'device')
1382         #print "Configuring PART %s" % (type)
1383         partstack.push(newpart)
1384         #print "  new PART tos is now %s\n" %partstack.tos().info()
1385         # just push TOS, so that we can pop later. 
1386         dirstack.push(dirstack.tos())
1387         
1388 def part(type, path, file, name):
1389         global curimage, dirstack, partstack
1390         partdir = os.path.join(type, path)
1391         srcdir = os.path.join(treetop, 'src')
1392         fulldir = os.path.join(srcdir, partdir)
1393         type_name = flatten_name(partdir)
1394         newpart = partobj(curimage, fulldir, partstack.tos(), type, \
1395                         type_name, name, 'chip')
1396         #print "Configuring PART %s, path %s" % (type, path)
1397         partstack.push(newpart)
1398         #print "  new PART tos is now %s\n" %partstack.tos().info()
1399         dirstack.push(fulldir)
1400         # special case for 'cpu' parts. 
1401         # we could add a new function too, but this is rather trivial.
1402         # if the part is a cpu, and we haven't seen it before, 
1403         # arrange to source the directory /cpu/'type'
1404         if (type == 'cpu'):
1405                 cpudir(path)
1406         else:
1407                 doconfigfile(srcdir, partdir, file, 'cfgfile')
1408
1409 def partpop():
1410         global dirstack, partstack
1411         curpart = partstack.tos()
1412         if (curpart == 0):
1413                 fatal("Trying to pop non-existent part")
1414         #print "End PART %s" % curpart.part
1415         # Warn if options are used without being set in this part
1416         for op in curpart.uses_options.keys():
1417                 if (not isset(op, curpart)):
1418                         notice("Option %s using default value %s" % (op, getformated(op, curpart.image)))
1419         oldpart = partstack.pop()
1420         dirstack.pop()
1421         #print "partstack.pop, TOS is now %s\n" % oldpart.info()
1422
1423 def dodir(path, file):
1424         """dodir is like part but there is no new part"""
1425         global dirstack
1426         # if the first char is '/', it is relative to treetop, 
1427         # else relative to curdir
1428         # os.path.join screws up if the name starts with '/', sigh.
1429         print "Configuring DIR %s" % os.path.join(path, file)
1430         if (path[0] == '/'):
1431                 fullpath = os.path.join(treetop, 'src')
1432                 path = re.sub('^/*', '', path)
1433         else:
1434                 fullpath = dirstack.tos()
1435         debug.info(debug.statement, "DODIR: path %s, fullpath %s" % (path, fullpath))
1436         dirstack.push(os.path.join(fullpath, path))
1437         doconfigfile(fullpath, path, file, 'cfgfile')
1438         dirstack.pop()
1439
1440 def lookup(name):
1441         global curimage
1442         return getoption(name, curimage)
1443
1444 def addrule(id):
1445         global curimage
1446         curimage.addmakerule(id)
1447         
1448 def adduserdefine(str):
1449         global curimage
1450         curimage.adduserdefine(str)
1451
1452 def addaction(id, str):
1453         global curimage
1454         curimage.addmakeaction(id, str)
1455
1456 def adddep(id, str):
1457         global curimage
1458         curimage.addmakedepend(id, str)
1459
1460 def setarch(my_arch):
1461         """arch is 'different' ... darn it."""
1462         global curimage
1463         print "SETTING ARCH %s\n" % my_arch
1464         curimage.setarch(my_arch)
1465         setdefault('ARCH', my_arch, 1)
1466         part('arch', my_arch, 'Config.lb', 0)
1467
1468 def doconfigfile(path, confdir, file, rule):
1469         rname = os.path.join(confdir, file)
1470         loc.push(rname)
1471         fullpath = os.path.join(path, rname)
1472         fp = safe_open(fullpath, 'r')
1473         if (not parse(rule, fp.read())):
1474                 fatal("Could not parse file")
1475         exitiferrors()
1476         loc.pop()
1477
1478 #=============================================================================
1479 #               MISC FUNCTIONS
1480 #=============================================================================
1481 def ternary(val, yes, no):
1482         debug.info(debug.statement, "ternary %s" % expr)
1483         debug.info(debug.statement, "expr %s a %d yes %d no %d"% (expr, a, yes, no))
1484         if (val == 0):
1485                 debug.info(debug.statement, "Ternary returns %d" % yes)
1486                 return yes
1487         else:
1488                 debug.info(debug.statement, "Ternary returns %d" % no)
1489                 return no
1490
1491 def tohex(name):
1492         """atoi is in the python library, but not strtol? Weird!"""
1493         return eval('int(%s)' % name)
1494
1495 def IsInt(str):
1496         """ Is the given string an integer?"""
1497         try:
1498                 num = long(str)
1499                 return 1
1500         except ValueError:
1501                 return 0
1502
1503 def dequote(str):
1504         a = re.sub("^\"", "", str)
1505         a = re.sub("\"$", "", a)
1506         # highly un-intuitive, need four \!
1507         a = re.sub("\\\\\"", "\"", a)
1508         return a
1509
1510 def flatten_name(str):
1511         a = re.sub("[/-]", "_", str)
1512         return a
1513
1514 def topify(path):
1515         """If the first part of <path> matches treetop, replace 
1516         that part with $(TOP)"""
1517         if path[0:len(treetop)] == treetop:
1518                 path = path[len(treetop):len(path)]
1519                 if (path[0:1] == "/"):
1520                         path = path[1:len(path)]
1521                 path = "$(TOP)/" + path
1522         return path
1523
1524 %%
1525 # to make if work without 2 passses, we use an old hack from SIMD, the 
1526 # context bit. If the bit is 1, then ops get done, otherwise
1527 # ops don't get done. From the top level, context is always
1528 # 1. In an if, context depends on eval of the if condition
1529
1530 parser Config:
1531     ignore:                     r'\s+'
1532     ignore:                     "#.*?\r?\n"
1533
1534     # less general tokens should come first, otherwise they get matched
1535     # by the re's
1536     token ACTION:               'action'
1537     token ADDACTION:            'addaction'
1538     token ALWAYS:               'always'
1539     token ARCH:                 'arch'
1540     token BUILDROM:             'buildrom'
1541     token COMMENT:              'comment'
1542     token CONFIG:               'config'
1543     token CPU:                  'cpu'
1544     token CHIP:                 'chip'
1545     token DEFAULT:              'default'
1546     token DEFINE:               'define'
1547     token DEPENDS:              'depends'
1548     token DEVICE:               'device'
1549     token DIR:                  'dir'
1550     token DRIVER:               'driver'
1551     token DRQ:                  'drq'
1552     token ELSE:                 'else'
1553     token END:                  'end'
1554     token EOF:                  '$'
1555     token EQ:                   '='
1556     token EXPORT:               'export'
1557     token FORMAT:               'format'
1558     token IF:                   'if'
1559     token INIT:                 'init'
1560     token INITOBJECT:           'initobject'
1561     token INITINCLUDE:          'initinclude'
1562     token IO:                   'io'
1563     token IRQ:                  'irq'
1564     token LDSCRIPT:             'ldscript'
1565     token LOADOPTIONS:          'loadoptions'
1566     token MAINBOARD:            'mainboard'
1567     token MAINBOARDINIT:        'mainboardinit'
1568     token MAKEDEFINE:           'makedefine'
1569     token MAKERULE:             'makerule'
1570     token MEM:                  'mem'
1571     token NEVER:                'never'
1572     token NONE:                 'none'
1573     token NORTHBRIDGE:          'northbridge'
1574     token OBJECT:               'object'
1575     token OPTION:               'option'
1576     token PAYLOAD:              'payload'
1577     token PMC:                  'pmc'
1578     token PRINT:                'print'
1579     token REGISTER:             'register'
1580     token ROMIMAGE:             'romimage'
1581     token SOUTHBRIDGE:          'southbridge'
1582     token SUPERIO:              'superio'
1583     token TARGET:               'target'
1584     token USED:                 'used'
1585     token USES:                 'uses'
1586     token WRITE:                'write'
1587     token NUM:                  '[0-9]+'
1588     token HEX_NUM:              '[0-9a-fA-F]+'
1589     token HEX_PREFIX:           '0x'
1590     # Why is path separate? Because paths to resources have to at least
1591     # have a slash, we thinks
1592     token PATH:                 r'[-a-zA-Z0-9_.][-a-zA-Z0-9/_.]+[-a-zA-Z0-9_.]+'
1593     # Dir's on the other hand are abitrary
1594     # this may all be stupid.
1595     token DIRPATH:              r'[-a-zA-Z0-9_$()./]+'
1596     token ID:                   r'[a-zA-Z_.]+[a-zA-Z0-9_.]*'
1597     token DELEXPR:              r'{([^}]+|\\.)*}'
1598     token STR:                  r'"([^\\"]+|\\.)*"'
1599     token RAWTEXT:              r'.*'
1600     token ON:                   'on'
1601     token OFF:                  'off'
1602     token PCI:                  'pci'
1603     token PNP:                  'pnp'
1604     token I2C:                  'i2c'
1605     token APIC:                 'apic'
1606     token APIC_CLUSTER:         'apic_cluster'
1607     token PCI_DOMAIN:           'pci_domain'
1608
1609
1610     rule expr:          logical                 {{ l = logical }}
1611                         ( "&&" logical          {{ l = l and logical }}
1612                         | "||"  logical         {{ l = l or logical }}
1613                         )*                      {{ return l }}
1614
1615     rule logical:       factor                  {{ n = factor }}
1616                         ( "[+]" factor          {{ n = n+factor }}
1617                         | "-"  factor           {{ n = n-factor }}
1618                         )*                      {{ return n }}
1619
1620     rule factor:        term                    {{ v = term }}
1621                         ( "[*]" term            {{ v = v*term }}
1622                         | "/"  term             {{ v = v/term }}
1623                         | "<<"  term            {{ v = v << term }}
1624                         | ">=" term             {{ v = (v < term)}}
1625                         )*                      {{ return v }}
1626
1627     # A term is a number, variable, or an expression surrounded by parentheses
1628     rule term:          NUM                     {{ return long(NUM, 10) }}
1629                 |       HEX_PREFIX HEX_NUM      {{ return long(HEX_NUM, 16) }}
1630                 |       ID                      {{ return lookup(ID) }}
1631                 |       unop                    {{ return unop }}
1632                 |       "\\(" expr "\\)"        {{ return expr }}
1633
1634     rule unop:          "!" expr                {{ return not(expr) }}
1635
1636     rule partend<<C>>:  (stmt<<C>>)* END        {{ if (C): partpop()}}
1637
1638     # This is needed because the legacy cpu command could not distinguish
1639     # between cpu vendors. It should just be PATH, but getting this change
1640     # into the source tree will be tricky... 
1641     # DO NOT USE ID AS IT MAY GO AWAY IN THE FUTURE
1642     rule partid:        ID                      {{ return ID }}
1643                 |       PATH                    {{ return PATH }}
1644
1645 #    rule parttype:     NORTHBRIDGE             {{ return 'northbridge' }} 
1646 #               |       SUPERIO                 {{ return 'superio' }}
1647 #               |       PMC                     {{ return 'pmc' }}
1648 #               |       SOUTHBRIDGE             {{ return 'southbridge' }}
1649 #               |       CPU                     {{ return 'cpu' }}
1650 #               |       CHIP                    {{ return '' }}
1651 #
1652     rule parttype:      CHIP                    {{ return '' }}
1653
1654     rule partdef<<C>>:                          {{ name = 0 }} 
1655                         parttype partid         
1656                         [ STR                   {{ name = dequote(STR) }}
1657                         ]                       {{ if (C): part(parttype, partid, 'Config.lb', name) }}
1658                         partend<<C>>            
1659
1660     rule arch<<C>>:     ARCH ID                 {{ if (C): setarch(ID) }}
1661                         partend<<C>>
1662     
1663     rule mainboardinit<<C>>:
1664                         MAINBOARDINIT DIRPATH   {{ if (C): addcrt0include(DIRPATH)}}
1665
1666     rule initinclude<<C>>: 
1667                         INITINCLUDE 
1668                         STR 
1669                         DIRPATH                 {{ if (C): addinitinclude(STR, DIRPATH)}}
1670
1671     rule initobject<<C>>:
1672                         INITOBJECT DIRPATH      {{ if (C): addinitobject(DIRPATH)}}
1673
1674     rule object<<C>>:   OBJECT DIRPATH          {{ if (C): addobject(DIRPATH)}}
1675
1676     rule driver<<C>>:   DRIVER DIRPATH          {{ if (C): adddriver(DIRPATH)}}
1677
1678     rule dir<<C>>:      DIR DIRPATH             {{ if (C): dodir(DIRPATH, 'Config.lb') }}
1679
1680     rule default<<C>>:  DEFAULT ID EQ value     {{ if (C): setdefault(ID, value, 0) }}
1681
1682     rule ldscript<<C>>: LDSCRIPT DIRPATH        {{ if (C): addldscript(DIRPATH) }}
1683
1684     rule iif<<C>>:      IF ID                   {{ c = lookup(ID) }}
1685                         (stmt<<C and c>>)* 
1686                         [ ELSE (stmt<<C and not c>>)* ]
1687                         END
1688
1689     rule depsacts<<ID, C>>:
1690                         ( DEPENDS STR           {{ if (C): adddep(ID, STR) }}
1691                         | ACTION STR            {{ if (C): addaction(ID, STR) }}
1692                         )*
1693
1694     rule makerule<<C>>: MAKERULE DIRPATH        {{ if (C): addrule(DIRPATH) }} 
1695                         depsacts<<DIRPATH, C>> 
1696                         END
1697
1698     rule makedefine<<C>>:
1699                         MAKEDEFINE RAWTEXT      {{ if (C): adduserdefine(RAWTEXT) }}
1700
1701     rule addaction<<C>>:
1702                         ADDACTION ID STR        {{ if (C): addaction(ID, STR) }}
1703
1704     rule init<<C>>:     INIT DIRPATH            {{ if (C): addinit(DIRPATH) }}
1705
1706     rule field:         STR                     {{ return STR }}
1707
1708     rule register<<C>>: REGISTER field '=' STR  {{ if (C): addregister(field, STR) }}
1709
1710     rule enable<<C>>:                           {{ val = 1 }}
1711                         ( ON                    {{ val = 1 }}
1712                         | OFF                   {{ val = 0 }}
1713                         )                       {{ if(C): partstack.tos().set_enabled(val) }}
1714
1715     rule resource<<C>>:                         {{ type = "" }}
1716                         (  IO                   {{ type = "IORESOURCE_FIXED | IORESOURCE_ASSIGNED | IORESOURCE_IO" }}
1717                         |   MEM                 {{ type = "IORESOURCE_FIXED | IORESOURCE_ASSIGNED | IORESOURCE_MEM" }}
1718                         |   IRQ                 {{ type = "IORESOURCE_FIXED | IORESOURCE_ASSIGNED | IORESOURCE_IRQ" }}
1719                         |   DRQ                 {{ type = "IORESOURCE_FIXED | IORESOURCE_ASSIGNED | IORESOURCE_DRQ" }}
1720                         )
1721                         term '='                {{ index = term }}
1722                         term                    {{ value = term }}
1723                                                 {{ if (C): partstack.tos().add_resource(type, index, value) }}
1724     
1725                              
1726     rule resources<<C>>:                        {{ if (C): partstack.tos().start_resources() }}
1727                         ( resource<<C>> )*
1728                                                 {{ if (C): partstack.tos().end_resources() }}
1729             
1730     
1731     rule pci<<C>>:      PCI                     {{ if (C): devicepart('pci') }}
1732
1733                         HEX_NUM                 {{ slot = int(HEX_NUM,16) }}
1734                         '.' HEX_NUM             {{ function = int(HEX_NUM, 16) }}
1735                                                 {{ if (C): partstack.tos().addpcipath(slot, function) }}
1736     rule pci_domain<<C>>:       
1737                         PCI_DOMAIN              {{ if (C): devicepart('pci_domain') }}
1738                         HEX_NUM                 {{ pci_domain = int(HEX_NUM, 16) }}
1739                                                 {{ if (C): partstack.tos().addpci_domainpath(pci_domain) }}
1740
1741     rule pnp<<C>>:      PNP                     {{ if (C): devicepart('pnp') }}
1742                         HEX_NUM                 {{ port = int(HEX_NUM,16) }}
1743                         '.' HEX_NUM             {{ device = int(HEX_NUM, 16) }}
1744                                                 {{ if (C): partstack.tos().addpnppath(port, device) }}
1745                                                 
1746     rule i2c<<C>>:      I2C                     {{ if (C): devicepart('i2c') }}
1747                         HEX_NUM                 {{ device = int(HEX_NUM, 16) }}
1748                                                 {{ if (C): partstack.tos().addi2cpath(device) }}
1749
1750     rule apic<<C>>:     APIC                    {{ if (C): devicepart('apic') }}
1751                         HEX_NUM                 {{ apic_id = int(HEX_NUM, 16) }}
1752                                                 {{ if (C): partstack.tos().addapicpath(apic_id) }}
1753
1754     rule apic_cluster<<C>>: APIC_CLUSTER        {{ if (C): devicepart('apic_cluster') }}
1755                         HEX_NUM                 {{ cluster = int(HEX_NUM, 16) }}
1756                                                 {{ if (C): partstack.tos().addapic_clusterpath(cluster) }}
1757
1758     rule dev_path<<C>>:                         
1759                         pci<<C>>                {{ return pci }}
1760                 |       pci_domain<<C>>         {{ return pci_domain }}
1761                 |       pnp<<C>>                {{ return pnp }}
1762                 |       i2c<<C>>                {{ return i2c }}
1763                 |       apic<<C>>               {{ return apic }}
1764                 |       apic_cluster<<C>>       {{ return apic_cluster }}
1765                 
1766     rule prtval:        expr                    {{ return str(expr) }}
1767                 |       STR                     {{ return STR }}
1768
1769     rule prtlist:       prtval                  {{ el = "%(" + prtval }}
1770                         ( "," prtval            {{ el = el + "," + prtval }}
1771                         )*                      {{ return el + ")" }}   
1772
1773     rule prtstmt<<C>>:  PRINT STR               {{ val = STR }}
1774                         [ "," prtlist           {{ val = val + prtlist }}
1775                         ]                       {{ if (C): print eval(val) }}
1776
1777     rule config<<C>>:   CONFIG PATH             {{ if (C): addconfig(PATH) }}
1778
1779     rule device<<C>>:   DEVICE dev_path<<C>>
1780                         enable<<C>>                     
1781                         resources<<C>>
1782                         partend<<C>> 
1783
1784     rule stmt<<C>>:     arch<<C>>               {{ return arch}}
1785                 |       addaction<<C>>          {{ return addaction }}
1786                 |       config<<C>>             {{ return config}}
1787                 |       default<<C>>            {{ return default}}
1788                 |       dir<<C>>                {{ return dir}}
1789                 |       driver<<C>>             {{ return driver }}
1790                 |       iif<<C>>                {{ return iif }}
1791                 |       init<<C>>               {{ return init }}
1792                 |       initinclude<<C>>        {{ return initinclude }}
1793                 |       initobject<<C>>         {{ return initobject }}
1794                 |       ldscript<<C>>           {{ return ldscript}}
1795                 |       mainboardinit<<C>>      {{ return mainboardinit }}
1796                 |       makedefine<<C>>         {{ return makedefine }}
1797                 |       makerule<<C>>           {{ return makerule }}
1798                 |       object<<C>>             {{ return object }}
1799                 |       option<<C>>             {{ return option }}
1800                 |       partdef<<C>>            {{ return partdef }}
1801                 |       prtstmt<<C>>            {{ return prtstmt }}
1802                 |       register<<C>>           {{ return register }}
1803                 |       device<<C>>             {{ return device }}
1804
1805     # ENTRY for parsing Config.lb file
1806     rule cfgfile:       (uses<<1>>)* 
1807                         (stmt<<1>>)*
1808                         EOF                     {{ return 1 }}
1809
1810     rule cfgfile:       (uses<<1>>)* 
1811                         (stmt<<1>>)*
1812                         EOF                     {{ return 1 }}
1813
1814     rule usesid<<C>>:   ID                      {{ if (C): usesoption(ID) }}
1815
1816     rule uses<<C>>:     USES (usesid<<C>>)+
1817
1818     rule mainboardvariables:    (uses<<1>>)*
1819                                 (default<<1>>)*
1820                                 (option<<1>>)*
1821                                 END             {{ return 1}}
1822
1823     rule value:         STR                     {{ return dequote(STR) }} 
1824                 |       expr                    {{ return expr }}
1825                 |       DELEXPR                 {{ return DELEXPR }}
1826
1827     rule option<<C>>:   OPTION ID EQ value      {{ if (C): setoption(ID, value, 0) }}
1828
1829     rule opif<<C>>:     IF ID                   {{ c = lookup(ID) }}
1830                         (opstmt<<C and c>>)* 
1831                         [ ELSE (opstmt<<C and not c>>)* ] 
1832                         END
1833
1834     rule opstmt<<C>>:   option<<C>>
1835                 |       opif<<C>>
1836                 |       prtstmt<<C>>
1837
1838     rule payload<<C>>:  PAYLOAD DIRPATH         {{ if (C): payload(DIRPATH) }}
1839
1840     rule mainboard:
1841                         MAINBOARD PATH          {{ mainboardsetup(PATH) }}
1842
1843     rule romif<<C>>:    IF ID                   {{ c = lookup(ID) }}
1844                         (romstmt<<C and c>>)* 
1845                         [ ELSE (romstmt<<C and not c>>)* ]
1846                         END
1847
1848     rule romstmt<<C>>:  romif<<C>>
1849                 |       option<<C>>
1850                 |       payload<<C>>
1851
1852     rule romimage:      ROMIMAGE STR            {{ startromimage(dequote(STR)) }}
1853                         (romstmt<<1>>)*
1854                         END                     {{ endromimage() }}
1855
1856     rule roms:          STR                     {{ s = '[' + STR }}
1857                         ( STR                   {{ s = s + "," + STR }}
1858                         )*                      {{ return eval(s + ']') }}
1859
1860     rule buildrom:      BUILDROM DIRPATH expr roms      {{ addbuildrom(DIRPATH, expr, roms) }}
1861
1862     rule romstmts:      romimage 
1863                 |       buildrom
1864                 |       opstmt<<1>>
1865
1866     # ENTRY for parsing root part
1867     rule board:         {{ loadoptions("config", "Options.lb", "options") }}
1868                         TARGET DIRPATH          {{ target(DIRPATH) }}
1869                         mainboard
1870                         (romstmts)*             
1871                         EOF                     {{ return 1 }}
1872
1873     # ENTRY for parsing a delayed value
1874     rule delexpr:       "{" expr "}" EOF        {{ return expr }}
1875
1876     rule wrstr<<ID>>:   STR                     {{ setwrite(ID, dequote(STR)) }}
1877
1878     rule defstmts<<ID>>:                        {{ d = 0 }}
1879                         ( DEFAULT
1880                           ( value               {{ setdefault(ID, value, 1) }}
1881                           | NONE                {{ setnodefault(ID) }}
1882                           )                     {{ d = d | 1 }}
1883                         | FORMAT STR            {{ setformat(ID, dequote(STR)) }}
1884                         | EXPORT 
1885                           ( ALWAYS              {{ setexported(ID) }}
1886                           | USED                {{ setexportable(ID) }}
1887                           | NEVER               {{ setnoexport(ID) }}
1888                           )                     {{ d = d | 2 }}
1889                         | COMMENT STR           {{ setcomment(ID, dequote(STR)); d = d | 4 }}
1890                         | WRITE (wrstr<<ID>>)+
1891                         )+                      {{ return d }}
1892                 
1893     rule define:        DEFINE ID               {{ newoption(ID) }}
1894                         defstmts<<ID>> END      {{ validdef(ID, defstmts) }}
1895
1896     # ENTRY for parsing Options.lb file
1897     rule options:       (define)* EOF           {{ return 1 }}
1898 %%
1899
1900 #=============================================================================
1901 #               FILE OUTPUT 
1902 #=============================================================================
1903 def writemakefileheader(file, fname):
1904         file.write("# File: %s is autogenerated\n" % fname)
1905
1906 def writemakefilefooter(file, fname):
1907         file.write("\n\n%s: %s %s\n"
1908                 % (os.path.basename(fname), os.path.abspath(sys.argv[0]), top_config_file))
1909         file.write("\t(cd %s ; %s %s %s)\n\n"
1910                 % (os.getcwd(), sys.argv[0], sys.argv[1], sys.argv[2]))
1911
1912 def writemakefilesettings(path):
1913         """ Write Makefile.settings to seperate the settings
1914         from the actual makefile creation."""
1915
1916         global treetop, target_dir
1917
1918         filename = os.path.join(path, "Makefile.settings")
1919         print "Creating", filename
1920         file = safe_open(filename, 'w+')
1921         writemakefileheader(file, filename)
1922         file.write("TOP:=%s\n" % (treetop))
1923         file.write("TARGET_DIR:=%s\n" % target_dir)
1924         writemakefilefooter(file, filename)
1925         file.close()
1926
1927 def writeimagesettings(image):
1928         """Write Makefile.settings to seperate the settings
1929         from the actual makefile creation."""
1930
1931         global treetop
1932         global global_options_by_order
1933
1934         filename = os.path.join(image.gettargetdir(), "Makefile.settings")
1935         print "Creating", filename
1936         file = safe_open(filename, 'w+')
1937         writemakefileheader(file, filename)
1938         file.write("TOP:=%s\n" % (treetop))
1939         file.write("TARGET_DIR:=%s\n" % (image.gettargetdir()))
1940         file.write("\n")
1941         exported = []
1942         for o in global_exported_options:
1943                 exported.append(o)
1944         for o in image.exported_options:
1945                 if (not o in exported):
1946                         exported.append(o)
1947         for o in exported:
1948                 file.write("export %s:=" % o.name)
1949                 if (hasvalue(o.name, image)):
1950                         file.write("%s" % getformated(o.name, image))
1951                 file.write("\n")
1952         file.write("\n")
1953         file.write("export VARIABLES :=\n")
1954         for o in exported:
1955                 file.write("export VARIABLES += %s\n" % o.name)
1956         file.write("\n")
1957         writemakefilefooter(file,filename)
1958         file.close()
1959
1960 # write the romimage makefile
1961 # let's try the Makefile
1962 # first, dump all the -D stuff
1963
1964 def writeimagemakefile(image):
1965         makefilepath = os.path.join(image.gettargetdir(), "Makefile")
1966         print "Creating", makefilepath
1967         file = safe_open(makefilepath, 'w+')
1968         writemakefileheader(file, makefilepath)
1969
1970         #file.write("include cpuflags\n")
1971         # Putting "include cpuflags" in the Makefile has the problem that the
1972         # cpuflags file would be generated _after_ we want to include it.
1973         # Instead, let make do the work of computing CPUFLAGS:
1974         file.write("# Get the value of TOP, VARIABLES, and several other variables.\n")
1975         file.write("include Makefile.settings\n\n")
1976         file.write("# Function to create an item like -Di586 or -DCONFIG_MAX_CPUS='1' or -Ui686\n")
1977         file.write("D_item = $(if $(subst undefined,,$(origin $1)),-D$1$(if $($1),='$($1)',),-U$1)\n\n")
1978         file.write("# Compute the value of CPUFLAGS here during make's first pass.\n")
1979         file.write("CPUFLAGS := $(foreach _var_,$(VARIABLES),$(call D_item,$(_var_)))\n\n")
1980
1981         for i in image.getuserdefines():
1982                 file.write("%s\n" %i)
1983         file.write("\n")
1984
1985         # main rule
1986         file.write("all: linuxbios.rom")
1987         # print out all the object dependencies
1988         file.write("\n# object dependencies (objectrules:)\n")
1989         file.write("INIT-OBJECTS :=\n")
1990         file.write("OBJECTS :=\n")
1991         file.write("DRIVER :=\n")
1992         file.write("\nSOURCES :=\n")
1993         for irule, init in image.getinitobjectrules().items():
1994                 i_name = init[0]
1995                 i_source = init[1]
1996                 file.write("INIT-OBJECTS += %s\n" % (i_name))
1997                 file.write("SOURCES += %s\n" % (i_source))
1998
1999         for objrule, obj in image.getobjectrules().items():
2000                 obj_name = obj[0]
2001                 obj_source = obj[1]
2002                 file.write("OBJECTS += %s\n" % (obj_name))
2003                 file.write("SOURCES += %s\n" % (obj_source))
2004
2005         # for chip_target.c
2006         file.write("OBJECTS += static.o\n")
2007         file.write("SOURCES += static.c\n")
2008
2009         for driverrule, driver in image.getdriverrules().items():
2010                 obj_name = driver[0]
2011                 obj_source = driver[1]
2012                 file.write("DRIVER += %s\n" % (obj_name))
2013                 file.write("SOURCES += %s\n" % (obj_source))
2014
2015         # Print out all ldscript.ld dependencies.
2016         file.write("\n# ldscript.ld dependencies:\n")
2017         file.write("LDSUBSCRIPTS-1 := \n" )
2018         for script in image.getldscripts():
2019                 file.write("LDSUBSCRIPTS-1 += %s\n" % topify(script))
2020
2021         # Print out the dependencies for crt0_includes.h
2022         file.write("\n# Dependencies for crt0_includes.h\n")
2023         file.write("CRT0_INCLUDES:=\n")
2024         for inc in image.getinitincludes():
2025                 if (local_path.match(inc)):
2026                         file.write("CRT0_INCLUDES += %s\n" % inc)
2027                 else:
2028                         file.write("CRT0_INCLUDES += $(TOP)/src/%s\n" % inc)
2029
2030         # Print out the user defines.
2031         file.write("\n# userdefines:\n")
2032                 
2033         # Print out the base rules.
2034         # Need to have a rule that counts on 'all'.
2035         file.write("\n# mainrulelist:")
2036
2037         # Print out any user rules.
2038         file.write("\n# From makerule or docipl commands:\n")
2039
2040         file.write("\n# initobjectrules:\n")
2041         for irule, init in image.getinitobjectrules().items():
2042                 source = topify(init[1])
2043                 type = init[2]
2044                 if (type  == 'S'):
2045                         # for .S, .o depends on .s
2046                         file.write("%s: %s.s\n" % (init[0], init[3]))
2047                         file.write("\t@echo $(CC) ... -o $@ $<\n")
2048                         file.write("\t$(CC) -c $(CPU_OPT) -o $@ $<\n")
2049                         # and .s depends on .S
2050                         file.write("%s.s: %s\n" % (init[3], source))
2051                         file.write("\t@echo $(CPP) ... $< > $@\n")
2052                         # Note: next 2 lines are ONE output line!
2053                         file.write("\t$(CPP) $(CPPFLAGS) $< ")
2054                         file.write(">$@.new && mv $@.new $@\n")
2055                 else:
2056                         file.write("%s: %s\n" % (init[0], source))
2057                         file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
2058
2059         file.write("\n# objectrules:\n")
2060         for objrule, obj in image.getobjectrules().items():
2061                 source = topify(obj[1])
2062                 type = obj[2]
2063                 if (type  == 'S'):
2064                         # for .S, .o depends on .s
2065                         file.write("%s: %s.s\n" % (obj[0], obj[3]))
2066                         file.write("\t@echo $(CC) ... -o $@ $<\n")
2067                         file.write("\t$(CC) -c $(CPU_OPT) -o $@ $<\n")
2068                         # and .s depends on .S
2069                         file.write("%s.s: %s\n" % (obj[3], source))
2070                         file.write("\t@echo $(CPP) ... $< > $@\n")
2071                         # Note: next 2 lines are ONE output line!
2072                         file.write("\t$(CPP) $(CPPFLAGS) $< ")
2073                         file.write(">$@.new && mv $@.new $@\n")
2074                 else:
2075                         file.write("%s: %s\n" % (obj[0], source))
2076                         file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
2077                 #file.write("%s\n" % objrule[2])
2078
2079         for driverrule, driver in image.getdriverrules().items():
2080                 source = topify(driver[1])
2081                 file.write("%s: %s\n" % (driver[0], source))
2082                 file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
2083                 #file.write("%s\n" % objrule[2])
2084
2085         # special rule for chip_target.c
2086         file.write("static.o: static.c\n")
2087         file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
2088
2089         # Print out the rules that will make cause the files
2090         # generated by NLBConfig.py to be remade if any dependencies change.
2091
2092         file.write("\n# Remember the automatically generated files\n")
2093         file.write("GENERATED:=\n")
2094         for genfile in ['Makefile',
2095                         'nsuperio.c',
2096                         'static.c',
2097                         'LinuxBIOSDoc.config' ]:
2098                 file.write("GENERATED += %s\n" % genfile)
2099         file.write("GENERATED += %s\n" % image.getincludefilename())
2100
2101         keys = global_options_by_order
2102         keys.sort()
2103         file.write("\necho:\n")
2104         for key in keys:
2105                  file.write("\t@echo %s='$(%s)'\n"% (key,key))
2106
2107         for i, m in image.getmakerules().items():
2108                 file.write("%s: " %i)
2109                 for i in m.dependency:
2110                         file.write("%s " % i)
2111                 file.write("\n")
2112                 for i in m.actions:
2113                         file.write("\t%s\n" % i)
2114         writemakefilefooter(file, makefilepath)
2115         file.close()
2116
2117 #
2118 def writemakefile(path):
2119         makefilepath = os.path.join(path, "Makefile")
2120         print "Creating", makefilepath
2121         file = safe_open(makefilepath, 'w+')
2122         writemakefileheader(file, makefilepath)
2123         file.write("include Makefile.settings\n\n")
2124
2125         # main rule
2126         file.write("all:")
2127         for i in buildroms:
2128                 file.write(" %s" % i.name)
2129         file.write("\n\n")      
2130         for i, o in romimages.items():
2131                 file.write("%s/linuxbios.rom:\n" % o.getname())
2132                 file.write("\tif (cd %s; \\\n" % o.getname())
2133                 file.write("\t\tmake linuxbios.rom)\\\n")
2134                 file.write("\tthen true; else exit 1; fi;\n\n")
2135         file.write("clean: ")
2136         for i in romimages.keys():
2137                 file.write(" %s-clean" % i)
2138         file.write("\n\n")
2139         for i, o in romimages.items():
2140                 file.write("%s-clean:\n" % o.getname())
2141                 file.write("\t(cd %s; make clean)\n\n" % o.getname())
2142
2143         for i in buildroms:
2144                 file.write("%s:" % i.name)
2145                 for j in i.roms:
2146                         file.write(" %s/linuxbios.rom " % j)
2147                 file.write("\n")
2148                 file.write("\t cat ")
2149                 for j in i.roms:
2150                         file.write(" %s/linuxbios.rom " % j)
2151                 file.write("> %s\n\n" %i.name)
2152
2153
2154         file.write(".PHONY: all clean")
2155         for i in romimages.keys():
2156                 file.write(" %s-clean" % i)
2157         file.write("\n\n")
2158
2159         writemakefilefooter(file, makefilepath)
2160         file.close()
2161
2162 def writeinitincludes(image):
2163         global include_pattern
2164         filepath = os.path.join(image.gettargetdir(), image.getincludefilename())
2165         print "Creating", filepath
2166         outfile = safe_open(filepath, 'w+')
2167         if (image.newformat()):
2168                 infile = safe_open(image.getinitfile(), 'r')
2169
2170                 line = infile.readline()
2171                 while (line):
2172                         p = include_pattern.match(line)
2173                         if (p):
2174                                 for i in image.getinitincludes():
2175                                         inc = image.getinitinclude(i)
2176                                         if (inc.getstring() == p.group(1)):
2177                                                 outfile.write("#include \"%s\"\n" % inc.getpath())
2178                         else:
2179                                 outfile.write(line)
2180                         line = infile.readline()
2181
2182                 infile.close()
2183         else:
2184                 for i in image.getinitincludes():
2185                         outfile.write("#include <%s>\n" % i)
2186         outfile.close()
2187
2188 def writeldoptions(image):
2189         """Write ldoptions file."""
2190         filename = os.path.join(image.gettargetdir(), "ldoptions")
2191         print "Creating", filename
2192         file = safe_open(filename, 'w+')
2193         for o in global_exported_options:
2194                 if (hasvalue(o.name, image) and IsInt(getoption(o.name, image))):
2195                         file.write("%s = %s;\n" % (o.name, getformated(o.name, image)))
2196         for o in image.exported_options:
2197                 if (not o in global_exported_options and hasvalue(o.name, image) and IsInt(getoption(o.name, image))):
2198                         file.write("%s = %s;\n" % (o.name, getformated(o.name, image)))
2199         file.close()
2200
2201 def dumptree(part, lvl):
2202         debug.info(debug.dumptree, "DUMPTREE ME is")
2203         part.dumpme(lvl)
2204         # dump the siblings -- actually are there any? not sure
2205         # siblings are:
2206         debug.info(debug.dumptree, "DUMPTREE SIBLINGS are")
2207         kid = part.next_sibling
2208         while (kid):
2209                 kid.dumpme(lvl)
2210                 kid = kid.next_sibling
2211         # dump the kids
2212         debug.info(debug.dumptree, "DUMPTREE KIDS are")
2213         #for kid in part.children:
2214         if (part.children):
2215                 dumptree(part.children, lvl+1)
2216         kid = part.next_sibling
2217         while (kid):
2218                 if (kid.children):
2219                         dumptree(kid.children, lvl + 1)
2220                 kid = kid.next_sibling
2221         debug.info(debug.dumptree, "DONE DUMPTREE")
2222
2223 def writecode(image):
2224         filename = os.path.join(img_dir, "static.c")
2225         print "Creating", filename
2226         file = safe_open(filename, 'w+')
2227         file.write("#include <device/device.h>\n")
2228         file.write("#include <device/pci.h>\n")
2229         for path in image.getconfigincludes().values():
2230                 file.write("#include \"%s\"\n" % path)
2231         gencode(image.getroot(), file, 0)
2232         gencode(image.getroot(), file, 1)
2233         file.close()
2234
2235 def gencode(part, file, pass_num):
2236         debug.info(debug.gencode, "GENCODE ME is")
2237         part.gencode(file, pass_num)
2238         # dump the siblings -- actually are there any? not sure
2239         debug.info(debug.gencode, "GENCODE SIBLINGS are")
2240         kid = part.next_sibling
2241         while (kid):
2242                 kid.gencode(file, pass_num)
2243                 kid = kid.next_sibling
2244         # now dump the children 
2245         debug.info(debug.gencode, "GENCODE KIDS are")
2246         if (part.children):
2247                 gencode(part.children, file, pass_num)
2248         kid = part.next_sibling
2249         while (kid):
2250                 if (kid.children):
2251                         gencode(kid.children, file, pass_num)
2252                 kid = kid.next_sibling
2253         debug.info(debug.gencode, "DONE GENCODE")
2254
2255 def verifyparse():
2256         """Add any run-time checks to verify that parsing the configuration
2257         was successful"""
2258
2259         for image in romimages.values():
2260                 print("Verifying ROMIMAGE %s" % image.name)
2261                 if (image.newformat() and image.getinitfile() == ''):
2262                         fatal("An init file must be specified")
2263                 for op in image.exported_options:
2264                         if (getoptionvalue(op.name, op, image) == 0 and getoptionvalue(op.name, op, 0) == 0):
2265                                 warning("Exported option %s has no value (check Options.lb)" % op.name);
2266         print("Verifing global options")
2267         for op in global_exported_options:
2268                 if (getoptionvalue(op.name, op, 0) == 0):
2269                         notice("Exported option %s has no value (check Options.lb)" % op.name);
2270                         
2271 #=============================================================================
2272 #               MAIN PROGRAM
2273 #=============================================================================
2274 if __name__=='__main__':
2275         from sys import argv
2276         if (len(argv) < 3):
2277                 fatal("Args: <file> <path to linuxbios>")
2278
2279         top_config_file = os.path.abspath(sys.argv[1])
2280
2281         treetop = os.path.abspath(sys.argv[2])
2282
2283         # Now read in the customizing script...
2284         loc.push(argv[1])
2285         fp = safe_open(argv[1], 'r')
2286         if (not parse('board', fp.read())):
2287                 fatal("Could not parse file")
2288         loc.pop()
2289
2290         verifyparse()
2291
2292         # no longer need to check if an options has been used
2293         alloptions = 1
2294
2295         for image_name, image in romimages.items():
2296                 if (debug.level(debug.dumptree)):
2297                         debug.info(debug.dumptree, "DEVICE TREE:")
2298                         dumptree(image.getroot(), 0)
2299
2300                 img_dir = image.gettargetdir()
2301                 if not os.path.isdir(img_dir):
2302                         print "Creating directory %s" % img_dir
2303                         os.makedirs(img_dir)
2304
2305                 if (debug.level(debug.dump)):
2306                         for i in image.getinitincludes():
2307                                 debug.info(debug.dump, "crt0include file %s" % i)
2308                         for i in image.getdriverrules().keys():
2309                                 debug.info(debug.dump, "driver file %s" % i)
2310                         for i in image.getldscripts():
2311                                 debug.info(debug.dump, "ldscript file %s" % i)
2312                         for i, m in image.getmakerules().items():
2313                                 debug.info(debug.dump, " makerule %s dep %s act %s" % (i, m.dependency, m.actions))
2314
2315                 writecode(image)
2316                 writeimagesettings(image)
2317                 writeinitincludes(image)
2318                 writeimagemakefile(image)
2319                 writeldoptions(image)
2320
2321         writemakefilesettings(target_dir)
2322         writemakefile(target_dir)
2323
2324         sys.exit(0)