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