13 global_options_by_order = []
14 global_option_values = {}
15 global_uses_options = {}
19 alloptions = 0 # override uses at top level
21 local_path = re.compile(r'^\.')
22 include_pattern = re.compile(r'%%([^%]+)%%')
24 # -----------------------------------------------------------------------------
26 # -----------------------------------------------------------------------------
29 """Used to keep track of the current part or dir"""
31 def __init__ (self, stack):
40 if (self.index < self.len):
41 s = self.stack[self.index]
42 self.index = self.index + 1
50 return len(self.stack)
52 def __getitem__ (self, i):
59 return self.__stack_iter(self.stack)
62 self.stack.append(part)
66 return self.stack.pop()
77 return (len(self.stack) == 0)
90 def __init__(self, *level):
93 def setdebug(self, *level):
96 def level(self, level):
97 return level in self.__level
99 def info(self, level, str):
100 if level in self.__level:
104 debug = debug_info(debug_info.none)
106 # -----------------------------------------------------------------------------
108 # -----------------------------------------------------------------------------
111 """Used to keep track of our current location while parsing
112 configuration files"""
114 def __init__(self, file, line, command):
117 self.command = command
118 def next_line(self, command):
119 self.line = self.line + 1
120 self.command = command
122 return "%s:%d" % (self.file, self.line)
133 s = s + '\n' + p.at()
137 return self.stack.tos().file
140 return self.stack.tos().line
143 return self.stack.tos().command
145 def push(self, file):
146 self.stack.push(self.__place(os.path.normpath(file), 0, ""))
151 def next_line(self, command):
152 self.stack.tos().next_line(command)
155 return self.stack.tos().at()
159 """Print error message"""
162 print "===> ERROR: %s" % string
166 """Print error message and exit"""
171 """Print warning message"""
173 warnings = warnings + 1
174 print "===> Warning: %s" % string
178 """Exit parser if an error has been encountered"""
182 # -----------------------------------------------------------------------------
184 # -----------------------------------------------------------------------------
187 """A rom image is the ultimate goal of linuxbios"""
188 def __init__ (self, name):
193 self.makebaserules = {}
194 self.objectrules = {}
195 self.initobjectrules = {}
196 self.driverrules = {}
198 self.userdefines = []
199 self.initincludes = {}
200 self.useinitincludes = 0 # transitional
201 self.partinstance = 0
204 self.values = {} # values of options set in romimage
212 def setarch(self, arch):
215 def setpayload(self, payload):
216 self.payload = payload
218 def setinitfile(self, initfile):
219 self.initfile = initfile
221 def getinitfile(self):
224 def addmakerule(self, id):
225 o = getdict(self.makebaserules, id)
227 print "Warning, rule %s previously defined" % id
229 setdict(self.makebaserules, id, o)
231 def getmakerules(self):
232 return self.makebaserules
234 def getmakerule(self, id):
235 o = getdict(self.makebaserules, id)
238 fatal("No such make rule \"%s\"" % id);
240 def addmakeaction(self, id, str):
241 o = getdict(self.makebaserules, id)
246 fatal("No such rule \"%s\" for addmakeaction" % id);
248 def addmakedepend(self, id, str):
249 o = getdict(self.makebaserules, id)
254 fatal("No such rule \"%s\" for addmakedepend" % id);
256 # this is called with an an object name.
257 # the easiest thing to do is add this object to the current
259 # such kludgery. If the name starts with '.' then make the
260 # dependency be on ./thing.x gag me.
261 def addobjectdriver(self, dict, object_name):
263 suffix = object_name[-2:]
266 base = object_name[:-2]
267 if (object_name[0] == '.'):
268 source = base + suffix
270 source = os.path.join(dirstack.tos(), base + suffix)
272 debug.info(debug.object, "add object %s source %s" % (object_name, source))
273 l = getdict(dict, base)
275 print "Warning, object/driver %s previously defined" % base
276 setdict(dict, base, [object, source])
278 def addinitobjectrule(self, name):
279 self.addobjectdriver(self.initobjectrules, name)
281 def addobjectrule(self, name):
282 self.addobjectdriver(self.objectrules, name)
284 def adddriverrule(self, name):
285 self.addobjectdriver(self.driverrules, name)
287 def getinitobjectrules(self):
288 return self.initobjectrules
290 def getinitobjectrule(self, name):
291 o = getdict(self.initobjectrules, name)
294 fatal("No such init object rule \"%s\"" % name);
296 def getobjectrules(self):
297 return self.objectrules
299 def getobjectrule(self, name):
300 o = getdict(self.objectrules, name)
303 fatal("No such object rule \"%s\"" % name);
305 def getdriverrules(self):
306 return self.driverrules
308 def getdriverrule(self, name):
309 o = getdict(self.driverrules, name)
312 fatal("No such driver rule \"%s\"" % name);
314 def addldscript(self, path):
315 self.ldscripts.append(path)
317 def getldscripts(self):
318 return self.ldscripts
320 def adduserdefine(self, str):
321 self.userdefines.append(str)
323 def getuserdefines(self):
324 return self.userdefines
326 def addinitinclude(self, str, path):
328 self.useinitincludes = 1
330 debug.info(debug.object, "ADDCRT0: %s -> %s" % (str, path))
331 o = getdict(self.initincludes, path)
333 print "Warning, init include for %s previously defined" % path
334 o = initinclude(str, path)
335 setdict(self.initincludes, path, o)
337 def getinitincludes(self):
338 return self.initincludes
340 def getinitinclude(self, path):
341 o = getdict(self.initincludes, path)
344 fatal("No such init include \"%s\"" % path);
346 def getincludefilename(self):
347 if (self.useinitincludes):
350 return "crt0_include.h"
353 return self.useinitincludes
356 return self.partinstance
358 def newpartinstance(self):
359 i = self.partinstance
360 self.partinstance = self.partinstance + 1
363 def setroot(self, part):
369 def settargetdir(self, path):
370 self.targetdir = path
372 def gettargetdir(self):
373 return self.targetdir
376 """A buildrom statement"""
377 def __init__ (self, size, roms):
382 """include file for initialization code"""
383 def __init__ (self, str, path):
394 """Rule to be included in Makefile"""
395 def __init__ (self, target):
400 def addaction(self, action):
401 self.actions.append(action)
403 def adddependency(self, dependency):
404 self.dependency.append(dependency)
409 def gdependency(self):
410 return self.dependency
416 """Configuration option"""
417 def __init__ (self, name):
418 self.name = name # name of option
419 self.loc = 0 # current location
420 self.set = 0 # option has been set
421 self.used = 0 # option has been set
422 self.default = 0 # option has default value (otherwise
424 self.comment = '' # description of option
425 self.exportable = 0 # option is able to be exported
426 self.exported = 0 # option is exported
427 self.defined = 0 # option has a value
428 self.format = '%s' # option print format
430 def setvalue(self, value, values, loc):
435 setdict(values, self.name, value)
437 def getvalue(self, image, values):
439 v = getdict(values, self.name)
443 if (not (type(val) is str)):
445 if (val == '' or val[0] != '{'):
449 val = parse('delexpr', val)
451 # TODO: need to check for parse errors!
452 return option_value(val)
454 def setdefault(self, value, loc):
455 global global_option_values
457 fatal("Error: default value for %s already set" % self.name)
458 setdict(global_option_values, self.name, value)
463 def setnodefault(self, loc):
471 def setcomment(self, comment, loc):
472 if (self.comment != ''):
473 print "%s: " % self.name
474 print "Attempt to modify comment at %s" % loc
476 self.comment = comment
478 def setexportable(self):
481 def setexported(self):
485 def setnoexport(self):
489 def setformat(self, fmt):
496 if (self.exportable):
500 def isexported(self):
501 return (self.exported and self.defined)
503 # def isdefined(self):
504 # return (self.defined)
513 """Value of a configuration option"""
514 def __init__(self, value):
521 """A configuration part"""
522 def __init__ (self, image, dir, parent, type, name):
523 debug.info(debug.object, "partobj dir %s parent %s type %s" %(dir,parent,type))
528 self.registercode = []
529 # sibling is not a list.
534 self.instance = image.newpartinstance()
535 self.flatten_name = flatten_name(type + "/" + name)
536 debug.info(debug.object, "INSTANCE %d" % self.instance)
539 self.uses_options = {}
540 # chip initialization. If there is a chip.h in the
541 # directory, generate the structs etc. to
542 # initialize the code
543 if (os.path.exists(dir + "/" + "chip.h")):
549 debug.info(debug.gencode, "add to parent")
551 # add current child as my sibling,
553 if (parent.children):
554 debug.info(debug.gencode, "add %s (%d) as sibling" % (parent.children.dir, parent.children.instance))
555 self.siblings = parent.children
556 parent.children = self
560 def dumpme(self, lvl):
561 print "%d: type %s" % (lvl, self.type)
562 print "%d: instance %d" % (lvl, self.instance)
563 print "%d: dir %s" % (lvl,self.dir)
564 print "%d: flatten_name %s" % (lvl,self.flatten_name)
565 print "%d: parent %s" % (lvl,self.parent.type)
566 print "%d: parent dir %s" % (lvl,self.parent.dir)
568 print "%d: child %s" % (lvl, self.children.dir)
570 print "%d: siblings %s" % (lvl, self.siblings.dir)
571 print "%d: initcode " % lvl
572 for i in self.initcode:
574 print "%d: registercode " % lvl
575 for i in self.registercode:
579 def gencode(self, file):
580 if (self.chipconfig):
581 debug.info(debug.gencode, "gencode: chipconfig(%d)" % self.instance)
582 file.write("#include \"%s/chip.h\"\n" % self.dir)
583 file.write("extern struct superio_control %s_control;\n" % \
585 file.write("struct %s_config %s_config_%d" % (\
587 self.flatten_name , \
589 if (self.registercode):
590 file.write("\t= {\n")
591 for i in self.registercode:
592 file.write( "\t %s" % i)
598 file.write("struct chip dev%d = {\n" % self.instance)
600 file.write("struct chip root = {\n")
601 file.write("/* %s %s */\n" % (self.type, self.dir))
602 #file.write(" .devfn = %d,\n" % self.devfn)
604 debug.info(debug.gencode, "gencode: siblings(%d)" % self.siblings.instance)
605 file.write(" .next = &dev%d,\n" % self.siblings.instance)
607 debug.info(debug.gencode, "gencode: children(%d)" % self.children.instance)
608 file.write(" .children = &dev%d,\n" % \
609 self.children.instance)
611 file.write(" .private = private%d,\n" % self.instance)
612 if (self.chipconfig):
613 # set the pointer to the structure for all this
615 file.write(" .control= &%s_control,\n" % \
617 # generate the pointer to the isntance
619 file.write(" .chip_config = (void *) &%s_config_%d,\n" %\
620 (self.flatten_name, self.instance ))
626 def addinit(self, code):
627 self.initcode.append(code)
629 def addregister(self, code):
631 self.registercode.append(code)
633 def usesoption(self, name):
634 global global_options
635 o = getdict(global_options, name)
637 fatal("Error: can't use undefined option %s" % name)
639 o1 = getdict(self.uses_options, name)
642 setdict(self.uses_options, name, o)
644 # -----------------------------------------------------------------------------
646 # -----------------------------------------------------------------------------
648 def getdict(dict, name):
649 if name not in dict.keys():
650 debug.info(debug.dict, "Undefined: %s" % name)
652 v = dict.get(name, 0)
653 debug.info(debug.dict, "getdict %s returning %s" % (name, v))
656 def setdict(dict, name, value):
657 debug.info(debug.dict, "setdict sets %s to %s" % (name, value))
661 # to create an option, it has to not exist.
662 # When an option value is fetched, the fact that it was used is
664 # Legal things to do:
665 # set a default value, then set a real value before the option is used.
666 # set a value, try to set a default, default silently fails.
668 # use the value, then try to set the value
671 global global_options, global_options_by_order
672 o = getdict(global_options, name)
674 print "option %s already defined" % name
677 setdict(global_options, name, o)
678 global_options_by_order.append(name)
680 def getoption(name, image):
681 """option must be declared before being used in a part
682 if we're not processing a part, then we must
683 be at the top level where all options are available
684 global global_uses_options, global_option_values"""
685 curpart = partstack.tos()
687 o = getdict(curpart.uses_options, name)
689 o = getdict(global_options, name)
691 o = getdict(global_uses_options, name)
692 if (o == 0 or not o.defined):
693 error("Option %s undefined (missing use command?)" % name)
697 v = o.getvalue(image, image.getvalues())
699 v = o.getvalue(image, global_option_values)
702 def setoption(name, value):
703 global loc, global_options, global_option_values, curimage
704 curpart = partstack.tos()
705 if (curpart and curpart.type != 'mainboard'):
706 fatal("Options may only be set in top-level and mainboard configuration files")
707 o = getdict(global_options, name)
709 fatal("Attempt to set nonexistent option %s" % name)
710 v = option_value(value)
712 o.setvalue(v, curimage.getvalues(), loc)
714 o.setvalue(v, global_option_values, loc)
716 def setdefault(name, value):
717 global loc, global_options
718 o = getdict(global_options, name)
722 print "setdefault: attempt to duplicate default for %s" % name
724 v = option_value(value)
727 def setnodefault(name):
728 global loc, global_options
729 o = getdict(global_options, name)
733 print "setdefault: attempt to duplicate default for %s" % name
737 def setcomment(name, value):
738 global loc, global_options
739 o = getdict(global_options, name)
741 fatal("setcomment: %s not here" % name)
742 o.setcomment(value, loc)
744 def setexported(name):
745 global global_options
746 o = getdict(global_options, name)
748 fatal("setexported: %s not here" % name)
751 def setnoexport(name):
752 global global_options
753 o = getdict(global_options, name)
755 fatal("setnoexport: %s not here" % name)
758 def setexportable(name):
759 global global_options
760 o = getdict(global_options, name)
762 fatal("setexportable: %s not here" % name)
765 def setformat(name, fmt):
766 global global_options
767 o = getdict(global_options, name)
769 fatal("setformat: %s not here" % name)
772 def getformated(name, image):
773 global global_options, global_option_values
774 o = getdict(global_options, name)
775 if (o == 0 or not o.defined):
776 fatal( "Option %s undefined." % name)
779 v = o.getvalue(image, image.getvalues())
781 v = o.getvalue(image, global_option_values)
783 return (f % v.contents())
785 def isexported(name):
786 global global_options
787 o = getdict(global_options, name)
789 return o.isexported()
792 #def isdefined(name, part):
793 # global global_options
795 # o = getdict(part.uses_options, name)
797 # o = getdict(global_options, name)
799 # return o.isdefined()
802 def isset(name, part):
803 global global_uses_options
805 o = getdict(part.uses_options, name)
807 o = getdict(global_uses_options, name)
812 #def isused(name, part):
813 # global global_options
815 # o = getdict(part.uses_options, name)
817 # o = getdict(global_options, name)
822 def usesoption(name):
823 global global_options, global_uses_options
824 curpart = partstack.tos()
826 curpart.usesoption(name)
828 o = getdict(global_options, name)
830 fatal("Can't use undefined option %s" % name)
832 o1 = getdict(global_uses_options, name)
835 setdict(global_uses_options, name, o)
837 def validdef(name, defval):
838 global global_options
839 o = getdict(global_options, name)
841 fatal("validdef: %s not here" % name)
842 if ((defval & 1) != 1):
843 fatal("Must specify default value for option %s" % name)
844 if ((defval & 2) != 2):
845 fatal("Must specify export for option %s" % name)
846 if ((defval & 4) != 4):
847 fatal("Must specify comment for option %s" % name)
850 file = os.path.join('src', 'config', 'Options.lb')
851 optionsfile = os.path.join(treetop, file)
853 if (not parse('options', open(optionsfile, 'r').read())):
854 fatal("Could not parse file")
858 global curimage, dirstack
860 curimage.setinitfile(treetop + '/src/' + path)
862 curimage.setinitfile(dirstack.tos() + '/' + path)
863 print "Adding init file: %s" % path
865 def addregister(code):
867 curpart = partstack.tos()
868 curpart.addregister(code)
870 def addcrt0include(path):
871 """we do the crt0include as a dictionary, so that if needed we
872 can trace who added what when. Also it makes the keys
875 curimage.addinitinclude(0, path)
877 def addinitinclude(str, path):
879 curimage.addinitinclude(dequote(str), path)
881 def addldscript(path):
882 global curimage, dirstack
883 curdir = dirstack.tos()
885 fullpath = treetop + '/src/' + path
887 fullpath = curdir + '/' + path
888 debug.info(debug.statement, "fullpath :%s: curdir :%s: path :%s:" % (fullpath, curdir, path))
889 curimage.addldscript(fullpath)
893 curimage.setpayload(path)
894 # adduserdefine("PAYLOAD:=%s"%path)
896 # adddep('payload', path)
897 # addaction('payload', 'cp $< $@')
899 def startromimage(name):
900 global romimages, curimage, target_dir, target_name
901 print "Configuring ROMIMAGE %s" % name
902 o = getdict(romimages, name)
904 fatal("romimage %s previously defined" % name)
905 curimage = romimage(name)
906 curimage.settargetdir(os.path.join(target_dir, name))
907 #o = partobj(curimage, target_dir, 0, 'board', target_name)
909 setdict(romimages, name, curimage)
918 full_path = os.path.join(treetop, 'src', 'mainboard', path)
919 setoption('MAINBOARD', full_path)
920 vendor = re.sub("/.*", "", path)
921 part_number = re.sub("[^/]*/", "", path)
922 setoption('MAINBOARD_VENDOR', vendor)
923 setoption('MAINBOARD_PART_NUMBER', part_number)
924 dodir('/config', 'Config.lb')
925 part('mainboard', path, 'Config.lb')
926 curimage.setroot(partstack.tos())
929 def addbuildrom(size, roms):
931 print "Build ROM size %d" % size
932 b = buildrom(size, roms)
935 def addinitobject(object_name):
937 curimage.addinitobjectrule(object_name)
939 def addobject(object_name):
941 curimage.addobjectrule(object_name)
943 def adddriver(driver_name):
945 curimage.adddriverrule(driver_name)
948 global target_dir, target_name
949 print "Configuring TARGET %s" % name
951 target_dir = os.path.join(os.path.dirname(loc.file()), name)
952 if not os.path.isdir(target_dir):
953 print "Creating directory %s" % target_dir
954 os.makedirs(target_dir)
955 print "Will place Makefile, crt0.S, etc. in %s" % target_dir
958 def part(name, path, file):
959 global curimage, dirstack, partstack
960 partdir = os.path.join(name, path)
961 srcdir = os.path.join(treetop, 'src')
962 fulldir = os.path.join(srcdir, partdir)
963 newpart = partobj(curimage, fulldir, partstack.tos(), name, path)
964 print "Configuring PART %s, path %s" % (name, path)
965 partstack.push(newpart)
966 dirstack.push(fulldir)
967 doconfigfile(srcdir, partdir, file)
970 global dirstack, partstack
971 curpart = partstack.pop()
973 fatal("Trying to pop non-existent part")
974 print "End PART %s" % curpart.type
975 # Warn if options are used without being set in this part
976 for i in curpart.uses_options.keys():
977 if (not isset(i, curpart)):
978 print "WARNING: Option %s using default value %s" % (i, getformated(i, curpart.image))
981 def dodir(path, file):
982 """dodir is like part but there is no new part"""
984 # if the first char is '/', it is relative to treetop,
985 # else relative to curdir
986 # os.path.join screws up if the name starts with '/', sigh.
987 print "Configuring DIR %s" % os.path.join(path, file)
989 fullpath = os.path.join(treetop, 'src')
990 path = re.sub('^/*', '', path)
992 fullpath = dirstack.tos()
993 debug.info(debug.statement, "DODIR: path %s, fullpath %s" % (path, fullpath))
994 dirstack.push(os.path.join(fullpath, path))
995 doconfigfile(fullpath, path, file)
1000 v = getoption(name, curimage)
1006 curimage.addmakerule(id)
1008 def adduserdefine(str):
1010 curimage.adduserdefine(str)
1012 def addaction(id, str):
1014 curimage.addmakeaction(id, str)
1016 def adddep(id, str):
1018 curimage.addmakedepend(id, str)
1020 def set_arch(my_arch):
1021 """arch is 'different' ... darn it."""
1023 curimage.setarch(my_arch)
1024 setoption('ARCH', my_arch)
1025 part('arch', my_arch, 'Config.lb')
1027 def doconfigfile(path, confdir, file):
1028 rname = os.path.join(confdir, file)
1030 fullpath = os.path.join(path, rname)
1031 if (not parse('cfgfile', open(fullpath, 'r').read())):
1032 fatal("Could not parse file")
1036 #=============================================================================
1038 #=============================================================================
1039 def ternary(val, yes, no):
1040 debug.info(debug.statement, "ternary %s" % expr)
1041 debug.info(debug.statement, "expr %s a %d yes %d no %d"% (expr, a, yes, no))
1043 debug.info(debug.statement, "Ternary returns %d" % yes)
1046 debug.info(debug.statement, "Ternary returns %d" % no)
1050 """atoi is in the python library, but not strtol? Weird!"""
1051 return eval('int(%s)' % name)
1054 """ Is the given string an integer?"""
1062 a = re.sub("^\"", "", str)
1063 a = re.sub("\"$", "", a)
1064 # highly un-intuitive, need four \!
1065 a = re.sub("\\\\\"", "\"", a)
1068 def flatten_name(str):
1069 a = re.sub("/", "_", str)
1073 """If the first part of <path> matches treetop, replace
1074 that part with $(TOP)"""
1075 if path[0:len(treetop)] == treetop:
1076 path = path[len(treetop):len(path)]
1077 if (path[0:1] == "/"):
1078 path = path[1:len(path)]
1079 path = "$(TOP)/" + path
1083 # to make if work without 2 passses, we use an old hack from SIMD, the
1084 # context bit. If the bit is 1, then ops get done, otherwise
1085 # ops don't get done. From the top level, context is always
1086 # 1. In an if, context depends on eval of the if condition
1092 # less general tokens should come first, otherwise they get matched
1094 token ACTION: 'action'
1095 token ADDACTION: 'addaction'
1096 token ALWAYS: 'always'
1098 token BUILDROM: 'buildrom'
1099 token COMMENT: 'comment'
1101 token DEFAULT: 'default'
1102 token DEFINE: 'define'
1103 token DEPENDS: 'depends'
1105 token DRIVER: 'driver'
1110 token EXPORT: 'export'
1111 token FORMAT: 'format'
1114 token INITOBJECT: 'initobject'
1115 token INITINCLUDE: 'initinclude'
1116 token LDSCRIPT: 'ldscript'
1117 token LOADOPTIONS: 'loadoptions'
1118 token MAINBOARD: 'mainboard'
1119 token MAINBOARDINIT: 'mainboardinit'
1120 token MAKEDEFINE: 'makedefine'
1121 token MAKERULE: 'makerule'
1122 token NEVER: 'never'
1124 token NORTHBRIDGE: 'northbridge'
1125 token OBJECT: 'object'
1126 token OPTION: 'option'
1127 token PAYLOAD: 'payload'
1129 token PRINT: 'print'
1130 token REGISTER: 'register'
1131 token ROMIMAGE: 'romimage'
1132 token SOUTHBRIDGE: 'southbridge'
1133 token SUPERIO: 'superio'
1134 token TARGET: 'target'
1137 token NUM: r'[0-9]+'
1138 token XNUM: r'0x[0-9a-fA-F]+'
1139 # Why is path separate? Because paths to resources have to at least
1140 # have a slash, we thinks
1141 token PATH: r'[a-zA-Z0-9_.][a-zA-Z0-9/_.]+[a-zA-Z0-9_.]+'
1142 # Dir's on the other hand are abitrary
1143 # this may all be stupid.
1144 token DIRPATH: r'[-a-zA-Z0-9_$()./]+'
1145 token ID: r'[a-zA-Z_.]+[a-zA-Z0-9_.]*'
1146 token DELEXPR: r'{([^}]+|\\.)*}'
1147 token STR: r'"([^\\"]+|\\.)*"'
1148 token RAWTEXT: r'.*'
1150 rule expr: logical {{ l = logical }}
1151 ( "&&" logical {{ l = l and logical }}
1152 | "||" logical {{ l = l or logical }}
1155 rule logical: factor {{ n = factor }}
1156 ( "[+]" factor {{ n = n+factor }}
1157 | "-" factor {{ n = n-factor }}
1160 rule factor: term {{ v = term }}
1161 ( "[*]" term {{ v = v*term }}
1162 | "/" term {{ v = v/term }}
1163 | "<<" term {{ v = v << term }}
1164 | ">=" term {{ v = (v < term)}}
1167 # A term is a number, variable, or an expression surrounded by parentheses
1168 rule term: NUM {{ return atoi(NUM) }}
1169 | XNUM {{ return tohex(XNUM) }}
1170 | ID {{ return lookup(ID) }}
1171 | unop {{ return unop }}
1172 | "\\(" expr "\\)" {{ return expr }}
1174 rule unop: "!" expr {{ return not(expr) }}
1176 rule partend<<C>>: (stmt<<C>>)* END {{ if (C): partpop()}}
1178 rule northbridge<<C>>:
1179 NORTHBRIDGE PATH {{ if (C): part('northbridge', PATH, 'Config.lb') }}
1182 rule superio<<C>>: SUPERIO PATH {{ if (C): part('superio', PATH, 'Config.lb') }}
1185 rule cpu<<C>>: CPU ID {{ if (C): part('cpu', ID, 'Config.lb') }}
1188 rule pmc<<C>>: PMC PATH {{ if (C): part('pmc', PATH, 'Config.lb') }}
1191 rule arch<<C>>: ARCH ID {{ if (C): set_arch(ID) }}
1194 rule southbridge<<C>>:
1195 SOUTHBRIDGE PATH {{ if (C): part('southbridge', PATH, 'Config.lb')}}
1198 rule mainboardinit<<C>>:
1199 MAINBOARDINIT DIRPATH {{ if (C): addcrt0include(DIRPATH)}}
1201 rule initinclude<<C>>:
1204 DIRPATH {{ if (C): addinitinclude(STR, DIRPATH)}}
1206 rule initobject<<C>>:
1207 INITOBJECT DIRPATH {{ if (C): addinitobject(DIRPATH)}}
1209 rule object<<C>>: OBJECT DIRPATH {{ if (C): addobject(DIRPATH)}}
1211 rule driver<<C>>: DRIVER DIRPATH {{ if (C): adddriver(DIRPATH)}}
1213 rule dir<<C>>: DIR DIRPATH {{ if (C): dodir(DIRPATH, 'Config.lb') }}
1215 rule ldscript<<C>>: LDSCRIPT DIRPATH {{ if (C): addldscript(DIRPATH) }}
1217 rule iif<<C>>: IF ID {{ c = lookup(ID) }}
1219 [ ELSE (stmt<<C and not c>>)* ]
1222 rule depsacts<<ID, C>>:
1223 ( DEPENDS STR {{ if (C): adddep(ID, STR) }}
1224 | ACTION STR {{ if (C): addaction(ID, STR) }}
1227 rule makerule<<C>>: MAKERULE DIRPATH {{ if (C): addrule(DIRPATH) }}
1228 depsacts<<DIRPATH, C>>
1231 rule makedefine<<C>>:
1232 MAKEDEFINE RAWTEXT {{ if (C): adduserdefine(RAWTEXT) }}
1234 rule addaction<<C>>:
1235 ADDACTION ID STR {{ if (C): addaction(ID, STR) }}
1237 rule init<<C>>: INIT DIRPATH {{ if (C): addinit(DIRPATH) }}
1239 rule register<<C>>: REGISTER STR {{ if (C): addregister(STR) }}
1241 rule prtval: expr {{ return str(expr) }}
1242 | STR {{ return STR }}
1244 rule prtlist: prtval {{ el = "%(" + prtval }}
1245 ( "," prtval {{ el = el + "," + prtval }}
1246 )* {{ return el + ")" }}
1248 rule prtstmt<<C>>: PRINT STR {{ val = STR }}
1249 [ "," prtlist {{ val = val + prtlist }}
1250 ] {{ if (C): print eval(val) }}
1252 rule stmt<<C>>: arch<<C>> {{ return arch}}
1253 | addaction<<C>> {{ return addaction }}
1254 | cpu<<C>> {{ return cpu}}
1255 | dir<<C>> {{ return dir}}
1256 | driver<<C>> {{ return driver }}
1257 | iif<<C>> {{ return iif }}
1258 | init<<C>> {{ return init }}
1259 | initinclude<<C>> {{ return initinclude }}
1260 | initobject<<C>> {{ return initobject }}
1261 | ldscript<<C>> {{ return ldscript}}
1262 | mainboardinit<<C>> {{ return mainboardinit }}
1263 | makedefine<<C>> {{ return makedefine }}
1264 | makerule<<C>> {{ return makerule }}
1265 | northbridge<<C>> {{ return northbridge }}
1266 | object<<C>> {{ return object }}
1267 | option<<C>> {{ return option }}
1268 | pmc<<C>> {{ return pmc}}
1269 | prtstmt<<C>> {{ return prtstmt}}
1270 | register<<C>> {{ return register}}
1271 | southbridge<<C>> {{ return southbridge }}
1272 | superio<<C>> {{ return superio }}
1274 # ENTRY for parsing Config.lb file
1275 rule cfgfile: (uses<<1>>)*
1279 rule usesid<<C>>: ID {{ if (C): usesoption(ID) }}
1281 rule uses<<C>>: USES (usesid<<C>>)+
1283 rule value: STR {{ return dequote(STR) }}
1284 | expr {{ return expr }}
1285 | DELEXPR {{ return DELEXPR }}
1287 rule option<<C>>: OPTION ID EQ value {{ if (C): setoption(ID, value) }}
1289 rule opif<<C>>: IF ID {{ c = lookup(ID) }}
1290 (opstmt<<C and c>>)*
1291 [ ELSE (opstmt<<C and not c>>)* ]
1294 rule opstmt<<C>>: option<<C>>
1298 rule payload<<C>>: PAYLOAD DIRPATH {{ if (C): payload(DIRPATH) }}
1300 rule mainboard<<C>>:
1301 MAINBOARD PATH {{ if (C): mainboard(PATH) }}
1303 rule romif<<C>>: IF ID {{ c = lookup(ID) }}
1304 (romstmt<<C and c>>)*
1305 [ ELSE (romstmt<<C and not c>>)* ]
1308 rule romstmt<<C>>: romif<<C>>
1313 rule romimage: ROMIMAGE STR {{ startromimage(dequote(STR)) }}
1315 END {{ endromimage() }}
1317 rule roms: STR {{ s = '(' + STR }}
1318 ( STR {{ s = s + "," + STR }}
1319 )* {{ return eval(s + ')') }}
1321 rule buildrom: BUILDROM expr roms {{ addbuildrom(expr, roms) }}
1323 rule romstmts: romimage
1327 # ENTRY for parsing root part
1328 rule board: LOADOPTIONS {{ loadoptions() }}
1329 TARGET DIRPATH {{ target(DIRPATH) }}
1334 # ENTRY for parsing a delayed value
1335 rule delexpr: "{" expr "}" EOF {{ return expr }}
1337 rule defstmts<<ID>>: {{ d = 0 }}
1339 ( value {{ setdefault(ID, value) }}
1340 | NONE {{ setnodefault(ID) }}
1342 | FORMAT STR {{ setformat(ID, dequote(STR)) }}
1344 ( ALWAYS {{ setexported(ID) }}
1345 | USED {{ setexportable(ID) }}
1346 | NEVER {{ setnoexport(ID) }}
1348 | COMMENT STR {{ setcomment(ID, dequote(STR)); d = d | 4 }}
1351 rule define: DEFINE ID {{ newoption(ID) }}
1352 defstmts<<ID>> END {{ validdef(ID, defstmts) }}
1354 # ENTRY for parsing Options.lb file
1355 rule options: (define)* EOF {{ return 1 }}
1358 #=============================================================================
1360 #=============================================================================
1361 def writemakefileheader(file, fname):
1362 file.write("# File: %s\n" % fname)
1363 file.write("# This file was generated by '%s %s %s'\n\n"
1364 % (sys.argv[0], sys.argv[1], sys.argv[2]))
1366 def writemakefilesettings(path):
1367 global treetop, target_dir
1368 # Write Makefile.settings to seperate the settings
1369 # from the actual makefile creation
1370 # In practice you need to rerun NLBConfig.py to change
1371 # these but in theory you shouldn't need to.
1373 filename = os.path.join(path, "Makefile.settings")
1374 print "Creating", filename
1375 file = open(filename, 'w+')
1376 writemakefileheader(file, filename)
1377 file.write("TOP:=%s\n" % (treetop))
1378 file.write("TARGET_DIR:=%s\n" % target_dir)
1379 # for i in global_options_by_order:
1380 # if (isexported(i, 0)):
1381 # file.write("export %s:=%s\n" % (i, getformated(i, 0)))
1382 # file.write("export VARIABLES := ")
1383 # for i in global_options.keys():
1384 # if (isexported(i, 0)):
1385 # file.write("%s " % i)
1389 def writeimagesettings(image):
1391 global global_options_by_order
1392 # Write Makefile.settings to seperate the settings
1393 # from the actual makefile creation
1394 # In practice you need to rerun NLBConfig.py to change
1395 # these but in theory you shouldn't need to.
1397 filename = os.path.join(image.gettargetdir(), "Makefile.settings")
1398 print "Creating", filename
1399 file = open(filename, 'w+')
1400 writemakefileheader(file, filename)
1401 file.write("TOP:=%s\n" % (treetop))
1402 file.write("TARGET_DIR:=%s\n" % (image.gettargetdir()))
1403 for i in global_options_by_order:
1405 file.write("export %s:=%s\n" % (i, getformated(i, image)))
1406 file.write("export VARIABLES := ")
1407 for i in global_options_by_order:
1409 file.write("%s " % i)
1413 # write the romimage makefile
1414 # let's try the Makefile
1415 # first, dump all the -D stuff
1417 def writeimagemakefile(image):
1418 makefilepath = os.path.join(image.gettargetdir(), "Makefile")
1419 print "Creating", makefilepath
1420 file = open(makefilepath, 'w+')
1421 writemakefileheader(file, makefilepath)
1423 #file.write("include cpuflags\n")
1424 # Putting "include cpuflags" in the Makefile has the problem that the
1425 # cpuflags file would be generated _after_ we want to include it.
1426 # Instead, let make do the work of computing CPUFLAGS:
1427 file.write("# Get the value of TOP, VARIABLES, and several other variables.\n")
1428 file.write("include Makefile.settings\n\n")
1429 file.write("# Function to create an item like -Di586 or -DMAX_CPUS='1' or -Ui686\n")
1430 file.write("D_item = $(if $(subst undefined,,$(origin $1)),-D$1$(if $($1),='$($1)',),-U$1)\n\n")
1431 file.write("# Compute the value of CPUFLAGS here during make's first pass.\n")
1432 file.write("CPUFLAGS := $(foreach _var_,$(VARIABLES),$(call D_item,$(_var_)))\n\n")
1434 for i in image.getuserdefines():
1435 file.write("%s\n" %i)
1439 file.write("all: linuxbios.rom")
1440 # print out all the object dependencies
1441 file.write("\n# object dependencies (objectrules:)\n")
1442 file.write("INIT-OBJECTS :=\n")
1443 file.write("OBJECTS :=\n")
1444 file.write("DRIVER :=\n")
1445 file.write("\nSOURCES :=\n")
1446 for irule, init in image.getinitobjectrules().items():
1449 file.write("INIT-OBJECTS += %s\n" % (i_name))
1450 file.write("SOURCES += %s\n" % (i_source))
1452 for objrule, obj in image.getobjectrules().items():
1455 file.write("OBJECTS += %s\n" % (obj_name))
1456 file.write("SOURCES += %s\n" % (obj_source))
1459 file.write("OBJECTS += chip_%s.o\n" % target_name)
1460 file.write("SOURCES += chip_%s.c\n" % target_name)
1462 for driverrule, driver in image.getdriverrules().items():
1463 obj_name = driver[0]
1464 obj_source = driver[1]
1465 file.write("DRIVER += %s\n" % (obj_name))
1466 file.write("SOURCES += %s\n" % (obj_source))
1468 # Print out all ldscript.ld dependencies.
1469 file.write("\n# ldscript.ld dependencies:\n")
1470 file.write("LDSUBSCRIPTS-1 := \n" )
1471 for script in image.getldscripts():
1472 file.write("LDSUBSCRIPTS-1 += %s\n" % topify(script))
1474 # Print out the dependencies for crt0_includes.h
1475 file.write("\n# Dependencies for crt0_includes.h\n")
1476 file.write("CRT0_INCLUDES:=\n")
1477 for inc in image.getinitincludes().keys():
1478 if (local_path.match(inc)):
1479 file.write("CRT0_INCLUDES += %s\n" % inc)
1481 file.write("CRT0_INCLUDES += $(TOP)/src/%s\n" % inc)
1483 # Print out the user defines.
1484 file.write("\n# userdefines:\n")
1485 #for udef in image.userdefines:
1486 #file.write("%s\n" % udef)
1488 # Print out the base rules.
1489 # Need to have a rule that counts on 'all'.
1490 file.write("\n# mainrulelist:")
1491 #file.write("\nmainrule: %s\n" % image.mainrulelist)
1493 # Print out any user rules.
1494 file.write("\n# From makerule or docipl commands:\n")
1495 # Old way (hash order): for target in makebaserules.keys():
1496 # New way (config file order):
1497 #for target in image.makerule_targets:
1498 #image.makebaserules[target].write(file)
1500 file.write("\n# objectrules:\n")
1501 for objrule, obj in image.getobjectrules().items():
1502 source = topify(obj[1])
1503 file.write("%s: %s\n" % (obj[0], source))
1504 file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
1505 #file.write("%s\n" % objrule[2])
1507 for driverrule, driver in image.getdriverrules().items():
1508 source = topify(driver[1])
1509 file.write("%s: %s\n" % (driver[0], source))
1510 file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
1511 #file.write("%s\n" % objrule[2])
1513 # special rule for chips_target.c
1514 file.write("chip_%s.o: chip_%s.c\n" % (target_name, target_name))
1515 file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
1517 # Print out the rules that will make cause the files
1518 # generated by NLBConfig.py to be remade if any dependencies change.
1520 file.write("\n# Remember the automatically generated files\n")
1521 file.write("GENERATED:=\n")
1522 for genfile in ['Makefile',
1524 'chip_%s.c' % target_name,
1525 'LinuxBIOSDoc.config' ]:
1526 file.write("GENERATED += %s\n" % genfile)
1527 file.write("GENERATED += %s\n" % image.getincludefilename())
1529 #file.write("\n# Remake Makefile (and the other files generated by\n")
1530 #file.write("# NLBConfig.py) if any config dependencies change.\n")
1532 #for cfile in image.config_file_list:
1533 # file.write("$(GENERATED): %s\n" % topify(cfile))
1535 #for depfile in [ '%s' % top_config_file, # This a duplicate, remove?
1536 # '$(TOP)/util/config/NLBConfig.py',
1537 # '$(TOP)/src/arch/$(ARCH)/config/make.base' ]:
1538 # file.write("$(GENERATED): %s\n" % depfile)
1540 #file.write("$(GENERATED):\n")
1541 #file.write("\tpython $(TOP)/util/config/NLBConfig.py %s $(TOP)\n"
1542 # % top_config_file)
1544 keys = image.getroot().uses_options.keys()
1546 file.write("\necho:\n")
1548 file.write("\t@echo %s='$(%s)'\n"% (key,key))
1550 for i, m in image.getmakerules().items():
1551 file.write("%s: " %i)
1552 for i in m.dependency:
1553 file.write("%s " % i)
1556 file.write("\t%s\n" % i)
1560 def writemakefile(path):
1561 makefilepath = os.path.join(path, "Makefile")
1562 print "Creating", makefilepath
1563 file = open(makefilepath, 'w+')
1564 writemakefileheader(file, makefilepath)
1568 for i in romimages.keys():
1569 file.write("%s-rom " % i)
1571 for i, o in romimages.items():
1572 file.write("%s-rom:\n" % o.getname())
1573 file.write("\tif (cd %s; \\\n" % o.getname())
1574 file.write("\t\tmake linuxbios.rom)\\\n");
1575 file.write("\tthen true; else exit 1; fi;\n\n")
1578 def writeinitincludes(image):
1579 global include_pattern
1580 filepath = os.path.join(image.gettargetdir(), image.getincludefilename())
1581 print "Creating", filepath
1582 outfile = open(filepath, 'w+')
1583 if (image.newformat()):
1584 infile = open(image.getinitfile(), 'r')
1586 line = infile.readline()
1588 p = include_pattern.match(line)
1590 for i, inc in image.getinitincludes().items():
1591 if (inc.getstring() == p.group(1)):
1592 outfile.write("#include \"%s\"\n" % inc.getpath())
1594 outfile.write(line);
1595 line = infile.readline()
1599 for i in image.getinitincludes().keys():
1600 outfile.write("#include <%s>\n" % i)
1603 def writeldoptions(image):
1604 # Write Makefile.settings to seperate the settings
1605 # from the actual makefile creation
1606 # In practice you need to rerun NLBConfig.py to change
1607 # these but in theory you shouldn't need to.
1609 filename = os.path.join(image.gettargetdir(), "ldoptions")
1610 print "Creating", filename
1611 file = open(filename, 'w+')
1612 for i in global_options.keys():
1613 if (isexported(i) and IsInt(getoption(i, image))):
1614 file.write("%s = %s;\n" % (i, getformated(i, image)))
1617 def dumptree(part, lvl):
1618 debug.info(debug.dumptree, "DUMPTREE ME is")
1620 # dump the siblings -- actually are there any? not sure
1622 debug.info(debug.dumptree, "DUMPTREE SIBLINGS are")
1628 debug.info(debug.dumptree, "DUMPTREE KIDS are")
1629 #for kid in part.children:
1631 dumptree(part.children, lvl+1)
1632 debug.info(debug.dumptree, "DONE DUMPTREE")
1634 def writecode(image):
1635 filename = os.path.join(img_dir, "chips_%s.c" % target_name)
1636 print "Creating", filename
1637 file = open(filename, 'w+')
1638 # gen all the forward references
1641 file.write("#include <device/chip.h>\n")
1642 file.write("struct chip ")
1643 while (i <= image.numparts()):
1645 file.write("cdev%d "% i)
1650 gencode(image.getroot(), file)
1653 def gencode(part, file):
1654 debug.info(debug.gencode, "GENCODE ME is")
1656 # dump the siblings -- actually are there any? not sure
1657 debug.info(debug.gencode, "GENCODE SIBLINGS are")
1662 # now dump the children
1663 debug.info(debug.gencode, "GENCODE KIDS are")
1665 gencode(part.children, file)
1669 gencode(kid.children, file)
1671 debug.info(debug.gencode, "DONE GENCODE")
1673 def verifyparse(image):
1674 """Add any run-time checks to verify that parsing the configuration
1676 if (image.newformat() and image.getinitfile() == ''):
1677 fatal("An init file must be specified")
1679 #=============================================================================
1681 #=============================================================================
1682 if __name__=='__main__':
1683 from sys import argv
1685 print 'Args: <file> <path to linuxbios>'
1688 top_config_file = os.path.abspath(sys.argv[1])
1690 treetop = os.path.abspath(sys.argv[2])
1692 # Now read in the customizing script...
1694 if (not parse('board', open(argv[1], 'r').read())):
1695 fatal("Could not parse file")
1698 for r in romimages.keys():
1699 verifyparse(getdict(romimages, r))
1701 # no longer need to check if an options has been used
1704 for image_name, image in romimages.items():
1705 if (debug.level(debug.dumptree)):
1706 debug.info(debug.dumptree, "DEVICE TREE:")
1707 dumptree(image.getroot(), 0)
1709 img_dir = image.gettargetdir()
1710 if not os.path.isdir(img_dir):
1711 print "Creating directory %s" % img_dir
1712 os.makedirs(img_dir)
1715 if (debug.level(debug.dump)):
1716 for i in image.getinitincludes().keys():
1717 debug.info(debug.dump, "crt0include file %s" % i)
1718 for i in image.getdriverrules().keys():
1719 debug.info(debug.dump, "driver file %s" % i)
1720 for i in image.getldscripts():
1721 debug.info(debug.dump, "ldscript file %s" % i)
1722 for i, m in image.getmakerules().items():
1723 debug.info(debug.dump, " makerule %s dep %s act %s" % (i, m.dependency, m.actions))
1726 writeimagesettings(image)
1727 writeinitincludes(image)
1728 writeimagemakefile(image)
1729 writeldoptions(image)
1731 writemakefilesettings(target_dir)
1732 writemakefile(target_dir)