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