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