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