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.initincludesorder = [] # need to preserve order
201 self.useinitincludes = 0 # transitional
202 self.partinstance = 0
205 self.values = {} # values of options set in romimage
213 def setarch(self, arch):
216 def setpayload(self, payload):
217 self.payload = payload
219 def setinitfile(self, initfile):
220 self.initfile = initfile
222 def getinitfile(self):
225 def addmakerule(self, id):
226 o = getdict(self.makebaserules, id)
228 print "Warning, rule %s previously defined" % id
230 setdict(self.makebaserules, id, o)
232 def getmakerules(self):
233 return self.makebaserules
235 def getmakerule(self, id):
236 o = getdict(self.makebaserules, id)
239 fatal("No such make rule \"%s\"" % id);
241 def addmakeaction(self, id, str):
242 o = getdict(self.makebaserules, id)
247 fatal("No such rule \"%s\" for addmakeaction" % id);
249 def addmakedepend(self, id, str):
250 o = getdict(self.makebaserules, id)
255 fatal("No such rule \"%s\" for addmakedepend" % id);
257 # this is called with an an object name.
258 # the easiest thing to do is add this object to the current
260 # such kludgery. If the name starts with '.' then make the
261 # dependency be on ./thing.x gag me.
262 def addobjectdriver(self, dict, object_name):
264 suffix = object_name[-2:]
267 base = object_name[:-2]
268 if (object_name[0] == '.'):
269 source = base + suffix
271 source = os.path.join(dirstack.tos(), base + suffix)
273 debug.info(debug.object, "add object %s source %s" % (object_name, source))
274 l = getdict(dict, base)
276 print "Warning, object/driver %s previously defined" % base
277 setdict(dict, base, [object, source])
279 def addinitobjectrule(self, name):
280 self.addobjectdriver(self.initobjectrules, name)
282 def addobjectrule(self, name):
283 self.addobjectdriver(self.objectrules, name)
285 def adddriverrule(self, name):
286 self.addobjectdriver(self.driverrules, name)
288 def getinitobjectrules(self):
289 return self.initobjectrules
291 def getinitobjectrule(self, name):
292 o = getdict(self.initobjectrules, name)
295 fatal("No such init object rule \"%s\"" % name);
297 def getobjectrules(self):
298 return self.objectrules
300 def getobjectrule(self, name):
301 o = getdict(self.objectrules, name)
304 fatal("No such object rule \"%s\"" % name);
306 def getdriverrules(self):
307 return self.driverrules
309 def getdriverrule(self, name):
310 o = getdict(self.driverrules, name)
313 fatal("No such driver rule \"%s\"" % name);
315 def addldscript(self, path):
316 self.ldscripts.append(path)
318 def getldscripts(self):
319 return self.ldscripts
321 def adduserdefine(self, str):
322 self.userdefines.append(str)
324 def getuserdefines(self):
325 return self.userdefines
327 def addinitinclude(self, str, path):
329 self.useinitincludes = 1
331 debug.info(debug.object, "ADDCRT0: %s -> %s" % (str, path))
332 o = getdict(self.initincludes, path)
334 print "Warning, init include for %s previously defined" % path
335 o = initinclude(str, path)
336 setdict(self.initincludes, path, o)
337 self.initincludesorder.append(path)
339 def getinitincludes(self):
340 return self.initincludesorder
342 def getinitinclude(self, path):
343 o = getdict(self.initincludes, path)
346 fatal("No such init include \"%s\"" % path);
348 def getincludefilename(self):
349 if (self.useinitincludes):
352 return "crt0_includes.h"
355 return self.useinitincludes
358 return self.partinstance
360 def newpartinstance(self):
361 i = self.partinstance
362 self.partinstance = self.partinstance + 1
365 def setroot(self, part):
371 def settargetdir(self, path):
372 self.targetdir = path
374 def gettargetdir(self):
375 return self.targetdir
378 """A buildrom statement"""
379 def __init__ (self, size, roms):
384 """include file for initialization code"""
385 def __init__ (self, str, path):
396 """Rule to be included in Makefile"""
397 def __init__ (self, target):
402 def addaction(self, action):
403 self.actions.append(action)
405 def adddependency(self, dependency):
406 self.dependency.append(dependency)
411 def gdependency(self):
412 return self.dependency
418 """Configuration option"""
419 def __init__ (self, name):
420 self.name = name # name of option
421 self.loc = 0 # current location
422 self.set = 0 # option has been set
423 self.used = 0 # option has been set
424 self.default = 0 # option has default value (otherwise
426 self.comment = '' # description of option
427 self.exportable = 0 # option is able to be exported
428 self.exported = 0 # option is exported
429 self.defined = 0 # option has a value
430 self.format = '%s' # option print format
432 def setvalue(self, value, values, loc):
437 setdict(values, self.name, value)
439 def getvalue(self, image, values):
441 v = getdict(values, self.name)
445 if (not (type(val) is str)):
447 if (val == '' or val[0] != '{'):
451 val = parse('delexpr', val)
453 # TODO: need to check for parse errors!
454 return option_value(val)
456 def setdefault(self, value, loc):
457 global global_option_values
459 fatal("Error: default value for %s already set" % self.name)
460 setdict(global_option_values, self.name, value)
465 def setnodefault(self, loc):
473 def setcomment(self, comment, loc):
474 if (self.comment != ''):
475 print "%s: " % self.name
476 print "Attempt to modify comment at %s" % loc
478 self.comment = comment
480 def setexportable(self):
483 def setexported(self):
487 def setnoexport(self):
491 def setformat(self, fmt):
498 if (self.exportable):
502 def isexported(self):
503 return (self.exported and self.defined)
505 # def isdefined(self):
506 # return (self.defined)
515 """Value of a configuration option"""
516 def __init__(self, value):
523 """A configuration part"""
524 def __init__ (self, image, dir, parent, type, name):
525 debug.info(debug.object, "partobj dir %s parent %s type %s" %(dir,parent,type))
530 self.registercode = []
531 # sibling is not a list.
536 self.instance = image.newpartinstance()
537 self.flatten_name = flatten_name(type + "/" + name)
538 debug.info(debug.object, "INSTANCE %d" % self.instance)
541 self.uses_options = {}
542 # chip initialization. If there is a chip.h in the
543 # directory, generate the structs etc. to
544 # initialize the code
545 if (os.path.exists(dir + "/" + "chip.h")):
551 debug.info(debug.gencode, "add to parent")
553 # add current child as my sibling,
555 if (parent.children):
556 debug.info(debug.gencode, "add %s (%d) as sibling" % (parent.children.dir, parent.children.instance))
557 self.siblings = parent.children
558 parent.children = self
562 def dumpme(self, lvl):
563 print "%d: type %s" % (lvl, self.type)
564 print "%d: instance %d" % (lvl, self.instance)
565 print "%d: dir %s" % (lvl,self.dir)
566 print "%d: flatten_name %s" % (lvl,self.flatten_name)
567 print "%d: parent %s" % (lvl,self.parent.type)
568 print "%d: parent dir %s" % (lvl,self.parent.dir)
570 print "%d: child %s" % (lvl, self.children.dir)
572 print "%d: siblings %s" % (lvl, self.siblings.dir)
573 print "%d: initcode " % lvl
574 for i in self.initcode:
576 print "%d: registercode " % lvl
577 for i in self.registercode:
581 def gencode(self, file):
582 if (self.chipconfig):
583 debug.info(debug.gencode, "gencode: chipconfig(%d)" % self.instance)
584 file.write("#include \"%s/chip.h\"\n" % self.dir)
585 file.write("extern struct chip_control %s_control;\n" % \
587 file.write("struct %s_config %s_config_%d" % (\
589 self.flatten_name , \
591 if (self.registercode):
592 file.write("\t= {\n")
593 for i in self.registercode:
594 file.write( "\t %s" % i)
600 file.write("struct chip dev%d = {\n" % self.instance)
602 file.write("struct chip root = {\n")
603 file.write("/* %s %s */\n" % (self.type, self.dir))
604 #file.write(" .devfn = %d,\n" % self.devfn)
606 debug.info(debug.gencode, "gencode: siblings(%d)" % self.siblings.instance)
607 file.write(" .next = &dev%d,\n" % self.siblings.instance)
609 debug.info(debug.gencode, "gencode: children(%d)" % self.children.instance)
610 file.write(" .children = &dev%d,\n" % \
611 self.children.instance)
613 file.write(" .private = private%d,\n" % self.instance)
614 if (self.chipconfig):
615 # set the pointer to the structure for all this
617 file.write(" .control= &%s_control,\n" % \
619 # generate the pointer to the isntance
621 file.write(" .chip_info = (void *) &%s_config_%d,\n" %\
622 (self.flatten_name, self.instance ))
628 def addinit(self, code):
629 self.initcode.append(code)
631 def addregister(self, code):
633 self.registercode.append(code)
635 def usesoption(self, name):
636 global global_options
637 o = getdict(global_options, name)
639 fatal("Error: can't use undefined option %s" % name)
641 o1 = getdict(self.uses_options, name)
644 setdict(self.uses_options, name, o)
646 # -----------------------------------------------------------------------------
648 # -----------------------------------------------------------------------------
650 def getdict(dict, name):
651 if name not in dict.keys():
652 debug.info(debug.dict, "Undefined: %s" % name)
654 v = dict.get(name, 0)
655 debug.info(debug.dict, "getdict %s returning %s" % (name, v))
658 def setdict(dict, name, value):
659 debug.info(debug.dict, "setdict sets %s to %s" % (name, value))
663 # to create an option, it has to not exist.
664 # When an option value is fetched, the fact that it was used is
666 # Legal things to do:
667 # set a default value, then set a real value before the option is used.
668 # set a value, try to set a default, default silently fails.
670 # use the value, then try to set the value
673 global global_options, global_options_by_order
674 o = getdict(global_options, name)
676 print "option %s already defined" % name
679 setdict(global_options, name, o)
680 global_options_by_order.append(name)
682 def getoption(name, image):
683 """option must be declared before being used in a part
684 if we're not processing a part, then we must
685 be at the top level where all options are available
686 global global_uses_options, global_option_values"""
687 curpart = partstack.tos()
689 o = getdict(curpart.uses_options, name)
691 o = getdict(global_options, name)
693 o = getdict(global_uses_options, name)
694 if (o == 0 or not o.defined):
695 error("Option %s undefined (missing use command?)" % name)
699 v = o.getvalue(image, image.getvalues())
701 v = o.getvalue(image, global_option_values)
704 def setoption(name, value):
705 global loc, global_options, global_option_values, curimage
706 curpart = partstack.tos()
707 if (curpart and curpart.type != 'mainboard'):
708 fatal("Options may only be set in top-level and mainboard configuration files")
709 o = getdict(global_options, name)
711 fatal("Attempt to set nonexistent option %s" % name)
712 v = option_value(value)
714 o.setvalue(v, curimage.getvalues(), loc)
716 o.setvalue(v, global_option_values, loc)
718 def setdefault(name, value):
719 global loc, global_options
720 o = getdict(global_options, name)
724 print "setdefault: attempt to duplicate default for %s" % name
726 v = option_value(value)
729 def setnodefault(name):
730 global loc, global_options
731 o = getdict(global_options, name)
735 print "setdefault: attempt to duplicate default for %s" % name
739 def setcomment(name, value):
740 global loc, global_options
741 o = getdict(global_options, name)
743 fatal("setcomment: %s not here" % name)
744 o.setcomment(value, loc)
746 def setexported(name):
747 global global_options
748 o = getdict(global_options, name)
750 fatal("setexported: %s not here" % name)
753 def setnoexport(name):
754 global global_options
755 o = getdict(global_options, name)
757 fatal("setnoexport: %s not here" % name)
760 def setexportable(name):
761 global global_options
762 o = getdict(global_options, name)
764 fatal("setexportable: %s not here" % name)
767 def setformat(name, fmt):
768 global global_options
769 o = getdict(global_options, name)
771 fatal("setformat: %s not here" % name)
774 def getformated(name, image):
775 global global_options, global_option_values
776 o = getdict(global_options, name)
777 if (o == 0 or not o.defined):
778 fatal( "Option %s undefined." % name)
781 v = o.getvalue(image, image.getvalues())
783 v = o.getvalue(image, global_option_values)
785 return (f % v.contents())
787 def isexported(name):
788 global global_options
789 o = getdict(global_options, name)
791 return o.isexported()
794 #def isdefined(name, part):
795 # global global_options
797 # o = getdict(part.uses_options, name)
799 # o = getdict(global_options, name)
801 # return o.isdefined()
804 def isset(name, part):
805 global global_uses_options
807 o = getdict(part.uses_options, name)
809 o = getdict(global_uses_options, name)
814 #def isused(name, part):
815 # global global_options
817 # o = getdict(part.uses_options, name)
819 # o = getdict(global_options, name)
824 def usesoption(name):
825 global global_options, global_uses_options
826 curpart = partstack.tos()
828 curpart.usesoption(name)
830 o = getdict(global_options, name)
832 fatal("Can't use undefined option %s" % name)
834 o1 = getdict(global_uses_options, name)
837 setdict(global_uses_options, name, o)
839 def validdef(name, defval):
840 global global_options
841 o = getdict(global_options, name)
843 fatal("validdef: %s not here" % name)
844 if ((defval & 1) != 1):
845 fatal("Must specify default value for option %s" % name)
846 if ((defval & 2) != 2):
847 fatal("Must specify export for option %s" % name)
848 if ((defval & 4) != 4):
849 fatal("Must specify comment for option %s" % name)
852 file = os.path.join('src', 'config', 'Options.lb')
853 optionsfile = os.path.join(treetop, file)
855 if (not parse('options', open(optionsfile, 'r').read())):
856 fatal("Could not parse file")
860 global curimage, dirstack
862 curimage.setinitfile(treetop + '/src/' + path)
864 curimage.setinitfile(dirstack.tos() + '/' + path)
865 print "Adding init file: %s" % path
867 def addregister(code):
869 curpart = partstack.tos()
870 curpart.addregister(code)
872 def addcrt0include(path):
873 """we do the crt0include as a dictionary, so that if needed we
874 can trace who added what when. Also it makes the keys
877 curimage.addinitinclude(0, path)
879 def addinitinclude(str, path):
881 curimage.addinitinclude(dequote(str), path)
883 def addldscript(path):
884 global curimage, dirstack
885 curdir = dirstack.tos()
887 fullpath = treetop + '/src/' + path
889 fullpath = curdir + '/' + path
890 debug.info(debug.statement, "fullpath :%s: curdir :%s: path :%s:" % (fullpath, curdir, path))
891 curimage.addldscript(fullpath)
895 curimage.setpayload(path)
896 # adduserdefine("PAYLOAD:=%s"%path)
898 # adddep('payload', path)
899 # addaction('payload', 'cp $< $@')
901 def startromimage(name):
902 global romimages, curimage, target_dir, target_name
903 print "Configuring ROMIMAGE %s" % name
904 o = getdict(romimages, name)
906 fatal("romimage %s previously defined" % name)
907 curimage = romimage(name)
908 curimage.settargetdir(os.path.join(target_dir, name))
909 #o = partobj(curimage, target_dir, 0, 'board', target_name)
911 setdict(romimages, name, curimage)
920 full_path = os.path.join(treetop, 'src', 'mainboard', path)
921 setoption('MAINBOARD', full_path)
922 vendor = re.sub("/.*", "", path)
923 part_number = re.sub("[^/]*/", "", path)
924 setoption('MAINBOARD_VENDOR', vendor)
925 setoption('MAINBOARD_PART_NUMBER', part_number)
926 dodir('/config', 'Config.lb')
927 part('mainboard', path, 'Config.lb')
928 curimage.setroot(partstack.tos())
931 def addbuildrom(size, roms):
933 print "Build ROM size %d" % size
934 b = buildrom(size, roms)
937 def addinitobject(object_name):
939 curimage.addinitobjectrule(object_name)
941 def addobject(object_name):
943 curimage.addobjectrule(object_name)
945 def adddriver(driver_name):
947 curimage.adddriverrule(driver_name)
950 global target_dir, target_name
951 print "Configuring TARGET %s" % name
953 target_dir = os.path.join(os.path.dirname(loc.file()), name)
954 if not os.path.isdir(target_dir):
955 print "Creating directory %s" % target_dir
956 os.makedirs(target_dir)
957 print "Will place Makefile, crt0.S, etc. in %s" % target_dir
960 def part(name, path, file):
961 global curimage, dirstack, partstack
962 partdir = os.path.join(name, path)
963 srcdir = os.path.join(treetop, 'src')
964 fulldir = os.path.join(srcdir, partdir)
965 newpart = partobj(curimage, fulldir, partstack.tos(), name, path)
966 print "Configuring PART %s, path %s" % (name, path)
967 partstack.push(newpart)
968 dirstack.push(fulldir)
969 doconfigfile(srcdir, partdir, file)
972 global dirstack, partstack
973 curpart = partstack.pop()
975 fatal("Trying to pop non-existent part")
976 print "End PART %s" % curpart.type
977 # Warn if options are used without being set in this part
978 for i in curpart.uses_options.keys():
979 if (not isset(i, curpart)):
980 print "WARNING: Option %s using default value %s" % (i, getformated(i, curpart.image))
983 def dodir(path, file):
984 """dodir is like part but there is no new part"""
986 # if the first char is '/', it is relative to treetop,
987 # else relative to curdir
988 # os.path.join screws up if the name starts with '/', sigh.
989 print "Configuring DIR %s" % os.path.join(path, file)
991 fullpath = os.path.join(treetop, 'src')
992 path = re.sub('^/*', '', path)
994 fullpath = dirstack.tos()
995 debug.info(debug.statement, "DODIR: path %s, fullpath %s" % (path, fullpath))
996 dirstack.push(os.path.join(fullpath, path))
997 doconfigfile(fullpath, path, file)
1002 v = getoption(name, curimage)
1008 curimage.addmakerule(id)
1010 def adduserdefine(str):
1012 curimage.adduserdefine(str)
1014 def addaction(id, str):
1016 curimage.addmakeaction(id, str)
1018 def adddep(id, str):
1020 curimage.addmakedepend(id, str)
1022 def set_arch(my_arch):
1023 """arch is 'different' ... darn it."""
1025 curimage.setarch(my_arch)
1026 setoption('ARCH', my_arch)
1027 part('arch', my_arch, 'Config.lb')
1029 def doconfigfile(path, confdir, file):
1030 rname = os.path.join(confdir, file)
1032 fullpath = os.path.join(path, rname)
1033 if (not parse('cfgfile', open(fullpath, 'r').read())):
1034 fatal("Could not parse file")
1038 #=============================================================================
1040 #=============================================================================
1041 def ternary(val, yes, no):
1042 debug.info(debug.statement, "ternary %s" % expr)
1043 debug.info(debug.statement, "expr %s a %d yes %d no %d"% (expr, a, yes, no))
1045 debug.info(debug.statement, "Ternary returns %d" % yes)
1048 debug.info(debug.statement, "Ternary returns %d" % no)
1052 """atoi is in the python library, but not strtol? Weird!"""
1053 return eval('int(%s)' % name)
1056 """ Is the given string an integer?"""
1064 a = re.sub("^\"", "", str)
1065 a = re.sub("\"$", "", a)
1066 # highly un-intuitive, need four \!
1067 a = re.sub("\\\\\"", "\"", a)
1070 def flatten_name(str):
1071 a = re.sub("/", "_", str)
1075 """If the first part of <path> matches treetop, replace
1076 that part with $(TOP)"""
1077 if path[0:len(treetop)] == treetop:
1078 path = path[len(treetop):len(path)]
1079 if (path[0:1] == "/"):
1080 path = path[1:len(path)]
1081 path = "$(TOP)/" + path
1085 # to make if work without 2 passses, we use an old hack from SIMD, the
1086 # context bit. If the bit is 1, then ops get done, otherwise
1087 # ops don't get done. From the top level, context is always
1088 # 1. In an if, context depends on eval of the if condition
1094 # less general tokens should come first, otherwise they get matched
1096 token ACTION: 'action'
1097 token ADDACTION: 'addaction'
1098 token ALWAYS: 'always'
1100 token BUILDROM: 'buildrom'
1101 token COMMENT: 'comment'
1103 token DEFAULT: 'default'
1104 token DEFINE: 'define'
1105 token DEPENDS: 'depends'
1107 token DRIVER: 'driver'
1112 token EXPORT: 'export'
1113 token FORMAT: 'format'
1116 token INITOBJECT: 'initobject'
1117 token INITINCLUDE: 'initinclude'
1118 token LDSCRIPT: 'ldscript'
1119 token LOADOPTIONS: 'loadoptions'
1120 token MAINBOARD: 'mainboard'
1121 token MAINBOARDINIT: 'mainboardinit'
1122 token MAKEDEFINE: 'makedefine'
1123 token MAKERULE: 'makerule'
1124 token NEVER: 'never'
1126 token NORTHBRIDGE: 'northbridge'
1127 token OBJECT: 'object'
1128 token OPTION: 'option'
1129 token PAYLOAD: 'payload'
1131 token PRINT: 'print'
1132 token REGISTER: 'register'
1133 token ROMIMAGE: 'romimage'
1134 token SOUTHBRIDGE: 'southbridge'
1135 token SUPERIO: 'superio'
1136 token TARGET: 'target'
1139 token NUM: r'[0-9]+'
1140 token XNUM: r'0x[0-9a-fA-F]+'
1141 # Why is path separate? Because paths to resources have to at least
1142 # have a slash, we thinks
1143 token PATH: r'[a-zA-Z0-9_.][a-zA-Z0-9/_.]+[a-zA-Z0-9_.]+'
1144 # Dir's on the other hand are abitrary
1145 # this may all be stupid.
1146 token DIRPATH: r'[-a-zA-Z0-9_$()./]+'
1147 token ID: r'[a-zA-Z_.]+[a-zA-Z0-9_.]*'
1148 token DELEXPR: r'{([^}]+|\\.)*}'
1149 token STR: r'"([^\\"]+|\\.)*"'
1150 token RAWTEXT: r'.*'
1152 rule expr: logical {{ l = logical }}
1153 ( "&&" logical {{ l = l and logical }}
1154 | "||" logical {{ l = l or logical }}
1157 rule logical: factor {{ n = factor }}
1158 ( "[+]" factor {{ n = n+factor }}
1159 | "-" factor {{ n = n-factor }}
1162 rule factor: term {{ v = term }}
1163 ( "[*]" term {{ v = v*term }}
1164 | "/" term {{ v = v/term }}
1165 | "<<" term {{ v = v << term }}
1166 | ">=" term {{ v = (v < term)}}
1169 # A term is a number, variable, or an expression surrounded by parentheses
1170 rule term: NUM {{ return atoi(NUM) }}
1171 | XNUM {{ return tohex(XNUM) }}
1172 | ID {{ return lookup(ID) }}
1173 | unop {{ return unop }}
1174 | "\\(" expr "\\)" {{ return expr }}
1176 rule unop: "!" expr {{ return not(expr) }}
1178 rule partend<<C>>: (stmt<<C>>)* END {{ if (C): partpop()}}
1180 rule northbridge<<C>>:
1181 NORTHBRIDGE PATH {{ if (C): part('northbridge', PATH, 'Config.lb') }}
1184 rule superio<<C>>: SUPERIO PATH {{ if (C): part('superio', PATH, 'Config.lb') }}
1187 rule cpu<<C>>: CPU ID {{ if (C): part('cpu', ID, 'Config.lb') }}
1190 rule pmc<<C>>: PMC PATH {{ if (C): part('pmc', PATH, 'Config.lb') }}
1193 rule arch<<C>>: ARCH ID {{ if (C): set_arch(ID) }}
1196 rule southbridge<<C>>:
1197 SOUTHBRIDGE PATH {{ if (C): part('southbridge', PATH, 'Config.lb')}}
1200 rule mainboardinit<<C>>:
1201 MAINBOARDINIT DIRPATH {{ if (C): addcrt0include(DIRPATH)}}
1203 rule initinclude<<C>>:
1206 DIRPATH {{ if (C): addinitinclude(STR, DIRPATH)}}
1208 rule initobject<<C>>:
1209 INITOBJECT DIRPATH {{ if (C): addinitobject(DIRPATH)}}
1211 rule object<<C>>: OBJECT DIRPATH {{ if (C): addobject(DIRPATH)}}
1213 rule driver<<C>>: DRIVER DIRPATH {{ if (C): adddriver(DIRPATH)}}
1215 rule dir<<C>>: DIR DIRPATH {{ if (C): dodir(DIRPATH, 'Config.lb') }}
1217 rule ldscript<<C>>: LDSCRIPT DIRPATH {{ if (C): addldscript(DIRPATH) }}
1219 rule iif<<C>>: IF ID {{ c = lookup(ID) }}
1221 [ ELSE (stmt<<C and not c>>)* ]
1224 rule depsacts<<ID, C>>:
1225 ( DEPENDS STR {{ if (C): adddep(ID, STR) }}
1226 | ACTION STR {{ if (C): addaction(ID, STR) }}
1229 rule makerule<<C>>: MAKERULE DIRPATH {{ if (C): addrule(DIRPATH) }}
1230 depsacts<<DIRPATH, C>>
1233 rule makedefine<<C>>:
1234 MAKEDEFINE RAWTEXT {{ if (C): adduserdefine(RAWTEXT) }}
1236 rule addaction<<C>>:
1237 ADDACTION ID STR {{ if (C): addaction(ID, STR) }}
1239 rule init<<C>>: INIT DIRPATH {{ if (C): addinit(DIRPATH) }}
1241 rule register<<C>>: REGISTER STR {{ if (C): addregister(STR) }}
1243 rule prtval: expr {{ return str(expr) }}
1244 | STR {{ return STR }}
1246 rule prtlist: prtval {{ el = "%(" + prtval }}
1247 ( "," prtval {{ el = el + "," + prtval }}
1248 )* {{ return el + ")" }}
1250 rule prtstmt<<C>>: PRINT STR {{ val = STR }}
1251 [ "," prtlist {{ val = val + prtlist }}
1252 ] {{ if (C): print eval(val) }}
1254 rule stmt<<C>>: arch<<C>> {{ return arch}}
1255 | addaction<<C>> {{ return addaction }}
1256 | cpu<<C>> {{ return cpu}}
1257 | dir<<C>> {{ return dir}}
1258 | driver<<C>> {{ return driver }}
1259 | iif<<C>> {{ return iif }}
1260 | init<<C>> {{ return init }}
1261 | initinclude<<C>> {{ return initinclude }}
1262 | initobject<<C>> {{ return initobject }}
1263 | ldscript<<C>> {{ return ldscript}}
1264 | mainboardinit<<C>> {{ return mainboardinit }}
1265 | makedefine<<C>> {{ return makedefine }}
1266 | makerule<<C>> {{ return makerule }}
1267 | northbridge<<C>> {{ return northbridge }}
1268 | object<<C>> {{ return object }}
1269 | option<<C>> {{ return option }}
1270 | pmc<<C>> {{ return pmc}}
1271 | prtstmt<<C>> {{ return prtstmt}}
1272 | register<<C>> {{ return register}}
1273 | southbridge<<C>> {{ return southbridge }}
1274 | superio<<C>> {{ return superio }}
1276 # ENTRY for parsing Config.lb file
1277 rule cfgfile: (uses<<1>>)*
1281 rule usesid<<C>>: ID {{ if (C): usesoption(ID) }}
1283 rule uses<<C>>: USES (usesid<<C>>)+
1285 rule value: STR {{ return dequote(STR) }}
1286 | expr {{ return expr }}
1287 | DELEXPR {{ return DELEXPR }}
1289 rule option<<C>>: OPTION ID EQ value {{ if (C): setoption(ID, value) }}
1291 rule opif<<C>>: IF ID {{ c = lookup(ID) }}
1292 (opstmt<<C and c>>)*
1293 [ ELSE (opstmt<<C and not c>>)* ]
1296 rule opstmt<<C>>: option<<C>>
1300 rule payload<<C>>: PAYLOAD DIRPATH {{ if (C): payload(DIRPATH) }}
1302 rule mainboard<<C>>:
1303 MAINBOARD PATH {{ if (C): mainboard(PATH) }}
1305 rule romif<<C>>: IF ID {{ c = lookup(ID) }}
1306 (romstmt<<C and c>>)*
1307 [ ELSE (romstmt<<C and not c>>)* ]
1310 rule romstmt<<C>>: romif<<C>>
1315 rule romimage: ROMIMAGE STR {{ startromimage(dequote(STR)) }}
1317 END {{ endromimage() }}
1319 rule roms: STR {{ s = '(' + STR }}
1320 ( STR {{ s = s + "," + STR }}
1321 )* {{ return eval(s + ')') }}
1323 rule buildrom: BUILDROM expr roms {{ addbuildrom(expr, roms) }}
1325 rule romstmts: romimage
1329 # ENTRY for parsing root part
1330 rule board: LOADOPTIONS {{ loadoptions() }}
1331 TARGET DIRPATH {{ target(DIRPATH) }}
1336 # ENTRY for parsing a delayed value
1337 rule delexpr: "{" expr "}" EOF {{ return expr }}
1339 rule defstmts<<ID>>: {{ d = 0 }}
1341 ( value {{ setdefault(ID, value) }}
1342 | NONE {{ setnodefault(ID) }}
1344 | FORMAT STR {{ setformat(ID, dequote(STR)) }}
1346 ( ALWAYS {{ setexported(ID) }}
1347 | USED {{ setexportable(ID) }}
1348 | NEVER {{ setnoexport(ID) }}
1350 | COMMENT STR {{ setcomment(ID, dequote(STR)); d = d | 4 }}
1353 rule define: DEFINE ID {{ newoption(ID) }}
1354 defstmts<<ID>> END {{ validdef(ID, defstmts) }}
1356 # ENTRY for parsing Options.lb file
1357 rule options: (define)* EOF {{ return 1 }}
1360 #=============================================================================
1362 #=============================================================================
1363 def writemakefileheader(file, fname):
1364 file.write("# File: %s\n" % fname)
1365 file.write("# This file was generated by '%s %s %s'\n\n"
1366 % (sys.argv[0], sys.argv[1], sys.argv[2]))
1368 def writemakefilesettings(path):
1369 global treetop, target_dir
1370 # Write Makefile.settings to seperate the settings
1371 # from the actual makefile creation
1372 # In practice you need to rerun NLBConfig.py to change
1373 # these but in theory you shouldn't need to.
1375 filename = os.path.join(path, "Makefile.settings")
1376 print "Creating", filename
1377 file = open(filename, 'w+')
1378 writemakefileheader(file, filename)
1379 file.write("TOP:=%s\n" % (treetop))
1380 file.write("TARGET_DIR:=%s\n" % target_dir)
1381 # for i in global_options_by_order:
1382 # if (isexported(i, 0)):
1383 # file.write("export %s:=%s\n" % (i, getformated(i, 0)))
1384 # file.write("export VARIABLES := ")
1385 # for i in global_options.keys():
1386 # if (isexported(i, 0)):
1387 # file.write("%s " % i)
1391 def writeimagesettings(image):
1393 global global_options_by_order
1394 # Write Makefile.settings to seperate the settings
1395 # from the actual makefile creation
1396 # In practice you need to rerun NLBConfig.py to change
1397 # these but in theory you shouldn't need to.
1399 filename = os.path.join(image.gettargetdir(), "Makefile.settings")
1400 print "Creating", filename
1401 file = open(filename, 'w+')
1402 writemakefileheader(file, filename)
1403 file.write("TOP:=%s\n" % (treetop))
1404 file.write("TARGET_DIR:=%s\n" % (image.gettargetdir()))
1405 for i in global_options_by_order:
1407 file.write("export %s:=%s\n" % (i, getformated(i, image)))
1408 file.write("export VARIABLES := ")
1409 for i in global_options_by_order:
1411 file.write("%s " % i)
1415 # write the romimage makefile
1416 # let's try the Makefile
1417 # first, dump all the -D stuff
1419 def writeimagemakefile(image):
1420 makefilepath = os.path.join(image.gettargetdir(), "Makefile")
1421 print "Creating", makefilepath
1422 file = open(makefilepath, 'w+')
1423 writemakefileheader(file, makefilepath)
1425 #file.write("include cpuflags\n")
1426 # Putting "include cpuflags" in the Makefile has the problem that the
1427 # cpuflags file would be generated _after_ we want to include it.
1428 # Instead, let make do the work of computing CPUFLAGS:
1429 file.write("# Get the value of TOP, VARIABLES, and several other variables.\n")
1430 file.write("include Makefile.settings\n\n")
1431 file.write("# Function to create an item like -Di586 or -DMAX_CPUS='1' or -Ui686\n")
1432 file.write("D_item = $(if $(subst undefined,,$(origin $1)),-D$1$(if $($1),='$($1)',),-U$1)\n\n")
1433 file.write("# Compute the value of CPUFLAGS here during make's first pass.\n")
1434 file.write("CPUFLAGS := $(foreach _var_,$(VARIABLES),$(call D_item,$(_var_)))\n\n")
1436 for i in image.getuserdefines():
1437 file.write("%s\n" %i)
1441 file.write("all: linuxbios.rom")
1442 # print out all the object dependencies
1443 file.write("\n# object dependencies (objectrules:)\n")
1444 file.write("INIT-OBJECTS :=\n")
1445 file.write("OBJECTS :=\n")
1446 file.write("DRIVER :=\n")
1447 file.write("\nSOURCES :=\n")
1448 for irule, init in image.getinitobjectrules().items():
1451 file.write("INIT-OBJECTS += %s\n" % (i_name))
1452 file.write("SOURCES += %s\n" % (i_source))
1454 for objrule, obj in image.getobjectrules().items():
1457 file.write("OBJECTS += %s\n" % (obj_name))
1458 file.write("SOURCES += %s\n" % (obj_source))
1461 file.write("OBJECTS += chip_%s.o\n" % target_name)
1462 file.write("SOURCES += chip_%s.c\n" % target_name)
1464 for driverrule, driver in image.getdriverrules().items():
1465 obj_name = driver[0]
1466 obj_source = driver[1]
1467 file.write("DRIVER += %s\n" % (obj_name))
1468 file.write("SOURCES += %s\n" % (obj_source))
1470 # Print out all ldscript.ld dependencies.
1471 file.write("\n# ldscript.ld dependencies:\n")
1472 file.write("LDSUBSCRIPTS-1 := \n" )
1473 for script in image.getldscripts():
1474 file.write("LDSUBSCRIPTS-1 += %s\n" % topify(script))
1476 # Print out the dependencies for crt0_includes.h
1477 file.write("\n# Dependencies for crt0_includes.h\n")
1478 file.write("CRT0_INCLUDES:=\n")
1479 for inc in image.getinitincludes():
1480 if (local_path.match(inc)):
1481 file.write("CRT0_INCLUDES += %s\n" % inc)
1483 file.write("CRT0_INCLUDES += $(TOP)/src/%s\n" % inc)
1485 # Print out the user defines.
1486 file.write("\n# userdefines:\n")
1487 #for udef in image.userdefines:
1488 #file.write("%s\n" % udef)
1490 # Print out the base rules.
1491 # Need to have a rule that counts on 'all'.
1492 file.write("\n# mainrulelist:")
1493 #file.write("\nmainrule: %s\n" % image.mainrulelist)
1495 # Print out any user rules.
1496 file.write("\n# From makerule or docipl commands:\n")
1497 # Old way (hash order): for target in makebaserules.keys():
1498 # New way (config file order):
1499 #for target in image.makerule_targets:
1500 #image.makebaserules[target].write(file)
1502 file.write("\n# objectrules:\n")
1503 for objrule, obj in image.getobjectrules().items():
1504 source = topify(obj[1])
1505 file.write("%s: %s\n" % (obj[0], source))
1506 file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
1507 #file.write("%s\n" % objrule[2])
1509 for driverrule, driver in image.getdriverrules().items():
1510 source = topify(driver[1])
1511 file.write("%s: %s\n" % (driver[0], source))
1512 file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
1513 #file.write("%s\n" % objrule[2])
1515 # special rule for chip_target.c
1516 file.write("chip_%s.o: chip_%s.c\n" % (target_name, target_name))
1517 file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
1519 # Print out the rules that will make cause the files
1520 # generated by NLBConfig.py to be remade if any dependencies change.
1522 file.write("\n# Remember the automatically generated files\n")
1523 file.write("GENERATED:=\n")
1524 for genfile in ['Makefile',
1526 'chip_%s.c' % target_name,
1527 'LinuxBIOSDoc.config' ]:
1528 file.write("GENERATED += %s\n" % genfile)
1529 file.write("GENERATED += %s\n" % image.getincludefilename())
1531 #file.write("\n# Remake Makefile (and the other files generated by\n")
1532 #file.write("# NLBConfig.py) if any config dependencies change.\n")
1534 #for cfile in image.config_file_list:
1535 # file.write("$(GENERATED): %s\n" % topify(cfile))
1537 #for depfile in [ '%s' % top_config_file, # This a duplicate, remove?
1538 # '$(TOP)/util/config/NLBConfig.py',
1539 # '$(TOP)/src/arch/$(ARCH)/config/make.base' ]:
1540 # file.write("$(GENERATED): %s\n" % depfile)
1542 #file.write("$(GENERATED):\n")
1543 #file.write("\tpython $(TOP)/util/config/NLBConfig.py %s $(TOP)\n"
1544 # % top_config_file)
1546 keys = image.getroot().uses_options.keys()
1548 file.write("\necho:\n")
1550 file.write("\t@echo %s='$(%s)'\n"% (key,key))
1552 for i, m in image.getmakerules().items():
1553 file.write("%s: " %i)
1554 for i in m.dependency:
1555 file.write("%s " % i)
1558 file.write("\t%s\n" % i)
1562 def writemakefile(path):
1563 makefilepath = os.path.join(path, "Makefile")
1564 print "Creating", makefilepath
1565 file = open(makefilepath, 'w+')
1566 writemakefileheader(file, makefilepath)
1570 for i in romimages.keys():
1571 file.write("%s-rom " % i)
1573 for i, o in romimages.items():
1574 file.write("%s-rom:\n" % o.getname())
1575 file.write("\tif (cd %s; \\\n" % o.getname())
1576 file.write("\t\tmake linuxbios.rom)\\\n");
1577 file.write("\tthen true; else exit 1; fi;\n\n")
1580 def writeinitincludes(image):
1581 global include_pattern
1582 filepath = os.path.join(image.gettargetdir(), image.getincludefilename())
1583 print "Creating", filepath
1584 outfile = open(filepath, 'w+')
1585 if (image.newformat()):
1586 infile = open(image.getinitfile(), 'r')
1588 line = infile.readline()
1590 p = include_pattern.match(line)
1592 for i in image.getinitincludes():
1593 inc = image.getinitinclude(i)
1594 if (inc.getstring() == p.group(1)):
1595 outfile.write("#include \"%s\"\n" % inc.getpath())
1597 outfile.write(line);
1598 line = infile.readline()
1602 for i in image.getinitincludes():
1603 outfile.write("#include <%s>\n" % i)
1606 def writeldoptions(image):
1607 # Write Makefile.settings to seperate the settings
1608 # from the actual makefile creation
1609 # In practice you need to rerun NLBConfig.py to change
1610 # these but in theory you shouldn't need to.
1612 filename = os.path.join(image.gettargetdir(), "ldoptions")
1613 print "Creating", filename
1614 file = open(filename, 'w+')
1615 for i in global_options.keys():
1616 if (isexported(i) and IsInt(getoption(i, image))):
1617 file.write("%s = %s;\n" % (i, getformated(i, image)))
1620 def dumptree(part, lvl):
1621 debug.info(debug.dumptree, "DUMPTREE ME is")
1623 # dump the siblings -- actually are there any? not sure
1625 debug.info(debug.dumptree, "DUMPTREE SIBLINGS are")
1631 debug.info(debug.dumptree, "DUMPTREE KIDS are")
1632 #for kid in part.children:
1634 dumptree(part.children, lvl+1)
1635 debug.info(debug.dumptree, "DONE DUMPTREE")
1637 def writecode(image):
1638 filename = os.path.join(img_dir, "chip_%s.c" % target_name)
1639 print "Creating", filename
1640 file = open(filename, 'w+')
1641 # gen all the forward references
1644 file.write("#include <device/chip.h>\n")
1645 file.write("struct chip ")
1646 while (i <= image.numparts()):
1648 file.write(", dev%d"% i)
1653 gencode(image.getroot(), file)
1656 def gencode(part, file):
1657 debug.info(debug.gencode, "GENCODE ME is")
1659 # dump the siblings -- actually are there any? not sure
1660 debug.info(debug.gencode, "GENCODE SIBLINGS are")
1665 # now dump the children
1666 debug.info(debug.gencode, "GENCODE KIDS are")
1668 gencode(part.children, file)
1672 gencode(kid.children, file)
1674 debug.info(debug.gencode, "DONE GENCODE")
1676 def verifyparse(image):
1677 """Add any run-time checks to verify that parsing the configuration
1679 if (image.newformat() and image.getinitfile() == ''):
1680 fatal("An init file must be specified")
1682 #=============================================================================
1684 #=============================================================================
1685 if __name__=='__main__':
1686 from sys import argv
1688 print 'Args: <file> <path to linuxbios>'
1691 top_config_file = os.path.abspath(sys.argv[1])
1693 treetop = os.path.abspath(sys.argv[2])
1695 # Now read in the customizing script...
1697 if (not parse('board', open(argv[1], 'r').read())):
1698 fatal("Could not parse file")
1701 for r in romimages.keys():
1702 verifyparse(getdict(romimages, r))
1704 # no longer need to check if an options has been used
1707 for image_name, image in romimages.items():
1708 if (debug.level(debug.dumptree)):
1709 debug.info(debug.dumptree, "DEVICE TREE:")
1710 dumptree(image.getroot(), 0)
1712 img_dir = image.gettargetdir()
1713 if not os.path.isdir(img_dir):
1714 print "Creating directory %s" % img_dir
1715 os.makedirs(img_dir)
1718 if (debug.level(debug.dump)):
1719 for i in image.getinitincludes():
1720 debug.info(debug.dump, "crt0include file %s" % i)
1721 for i in image.getdriverrules().keys():
1722 debug.info(debug.dump, "driver file %s" % i)
1723 for i in image.getldscripts():
1724 debug.info(debug.dump, "ldscript file %s" % i)
1725 for i, m in image.getmakerules().items():
1726 debug.info(debug.dump, " makerule %s dep %s act %s" % (i, m.dependency, m.actions))
1729 writeimagesettings(image)
1730 writeinitincludes(image)
1731 writeimagemakefile(image)
1732 writeldoptions(image)
1734 writemakefilesettings(target_dir)
1735 writemakefile(target_dir)