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