14 global_options_by_order = []
15 global_option_values = {}
16 global_uses_options = {}
23 alloptions = 0 # override uses at top level
25 local_path = re.compile(r'^\.')
26 include_pattern = re.compile(r'%%([^%]+)%%')
28 # -----------------------------------------------------------------------------
30 # -----------------------------------------------------------------------------
32 # Used to keep track of our current location while parsing
36 def __init__(self, file, line, command):
39 self.command = command
40 def next_line(self, command):
41 self.line = self.line + 1
42 self.command = command
44 return "%s:%d" % (self.file, self.line)
50 return self.stack[-1].file
52 return self.stack[-1].line
54 return self.stack[-1].command
56 def push_file(self, file):
57 self.stack.append(self.place(file, 0, ""))
60 def next_line(self, command):
61 self.stack[-1].next_line(command)
63 return self.stack[-1].at()
73 print loc.stack[i].at()
75 print "%s: %s"% (loc.at(), string)
77 # Print error message and exit
82 # Print warning message
85 warnings = warnings + 1
90 print loc.stack[i].at()
92 print "%s: %s"% (loc.at(), string)
94 # Exit parser if an error has been encountered
99 # -----------------------------------------------------------------------------
101 # -----------------------------------------------------------------------------
103 # A rom image is the ultimate goal of linuxbios
105 def __init__ (self, name):
110 self.makebaserules = {}
111 self.objectrules = {}
112 self.initobjectrules = {}
113 self.driverrules = {}
115 self.userdefines = []
116 self.initincludes = {}
117 self.useinitincludes = 0 # transitional
118 self.partinstance = 0
121 self.values = {} # values of options set in romimage
129 def setarch(self, arch):
132 def setpayload(self, payload):
133 self.payload = payload
135 def setinitfile(self, initfile):
136 self.initfile = initfile
138 def getinitfile(self):
141 def addmakerule(self, id):
142 o = getdict(self.makebaserules, id)
144 print "Warning, rule %s previously defined" % id
146 setdict(self.makebaserules, id, o)
148 def getmakerules(self):
149 return self.makebaserules
151 def getmakerule(self, id):
152 o = getdict(self.makebaserules, id)
155 fatal("No such make rule \"%s\"" % id);
157 def addmakeaction(self, id, str):
158 o = getdict(self.makebaserules, id)
163 fatal("No such rule \"%s\" for addmakeaction" % id);
165 def addmakedepend(self, id, str):
166 o = getdict(self.makebaserules, id)
171 fatal("No such rule \"%s\" for addmakedepend" % id);
173 # this is called with an an object name.
174 # the easiest thing to do is add this object to the current
176 # such kludgery. If the name starts with '.' then make the
177 # dependency be on ./thing.x gag me.
178 def addobjectdriver(self, dict, object_name):
180 suffix = object_name[-2:]
183 base = object_name[:-2]
184 if (object_name[0] == '.'):
185 source = base + suffix
187 source = os.path.join(curdir, base + suffix)
190 print "add object %s source %s" % (object_name, source)
191 l = getdict(dict, base)
193 print "Warning, object/driver %s previously defined" % base
194 setdict(dict, base, [object, source])
196 def addinitobjectrule(self, name):
197 self.addobjectdriver(self.initobjectrules, name)
199 def addobjectrule(self, name):
200 self.addobjectdriver(self.objectrules, name)
202 def adddriverrule(self, name):
203 self.addobjectdriver(self.driverrules, name)
205 def getinitobjectrules(self):
206 return self.initobjectrules
208 def getinitobjectrule(self, name):
209 o = getdict(self.initobjectrules, name)
212 fatal("No such init object rule \"%s\"" % name);
214 def getobjectrules(self):
215 return self.objectrules
217 def getobjectrule(self, name):
218 o = getdict(self.objectrules, name)
221 fatal("No such object rule \"%s\"" % name);
223 def getdriverrules(self):
224 return self.driverrules
226 def getdriverrule(self, name):
227 o = getdict(self.driverrules, name)
230 fatal("No such driver rule \"%s\"" % name);
232 def addldscript(self, path):
233 self.ldscripts.append(path)
235 def getldscripts(self):
236 return self.ldscripts
238 def adduserdefine(self, str):
239 self.userdefines.append(str)
241 def getuserdefines(self):
242 return self.userdefines
244 def addinitinclude(self, str, path):
246 self.useinitincludes = 1
249 print "ADDCRT0: %s -> %s" % str, path
250 o = getdict(self.initincludes, path)
252 print "Warning, init include for %s previously defined" % path
253 o = initinclude(str, path)
254 setdict(self.initincludes, path, o)
256 def getinitincludes(self):
257 return self.initincludes
259 def getinitinclude(self, path):
260 o = getdict(self.initincludes, path)
263 fatal("No such init include \"%s\"" % path);
265 def getincludefilename(self):
266 if (self.useinitincludes):
269 return "crt0_include.h"
272 return self.useinitincludes
274 def setpartinstance(self, val):
275 self.partinstance = val
277 def getpartinstance(self):
278 return self.partinstance
280 def setroot(self, part):
286 def settargetdir(self, path):
287 self.targetdir = path
289 def gettargetdir(self):
290 return self.targetdir
292 # A buildrom statement
294 def __init__ (self, size, roms):
298 # this is called with an an object name.
299 # the easiest thing to do is add this object to the current
301 # such kludgery. If the name starts with '.' then make the
302 # dependency be on ./thing.x gag me.
303 def addobjectdriver(dict, object_name):
304 global curimage, curdir
305 suffix = object_name[-2:]
308 base = object_name[:-2]
309 if (object_name[0] == '.'):
310 source = base + suffix
312 source = os.path.join(curdir, base + suffix)
315 print "add object %s source %s" % (object_name, source)
316 l = getdict(dict, base)
318 print "Warning, object/driver %s previously defined" % base
319 setdict(dict, base, [object, source])
321 # include file for initialization code
323 def __init__ (self, str, path):
333 # Rule to be included in Makefile
335 def __init__ (self, target):
340 def addaction(self, action):
341 self.actions.append(action)
343 def adddependency(self, dependency):
344 self.dependency.append(dependency)
349 def gdependency(self):
350 return self.dependency
355 # Configuration option
357 def __init__ (self, name):
358 self.name = name # name of option
359 self.loc = 0 # current location
360 #self.value = 0 # option value
361 self.set = 0 # option has been set
362 self.used = 0 # option has been set
363 self.default = 0 # option has default value (otherwise
365 self.comment = '' # description of option
366 self.exportable = 0 # option is able to be exported
367 self.exported = 0 # option is exported
368 self.defined = 0 # option has a value
369 self.format = '%s' # option print format
371 def setvalue(self, value, values, loc):
373 # fatal("Error: option %s already set" % self.name)
378 setdict(values, self.name, value)
380 def getvalue(self, image, values):
382 v = getdict(values, self.name)
386 if (not (type(val) is str)):
388 if (val == '' or val[0] != '{'):
392 val = parse('delexpr', val)
394 # TODO: need to check for parse errors!
395 return option_value(val)
397 def setdefault(self, value, loc):
398 global global_option_values
400 fatal("Error: default value for %s already set" % self.name)
402 setdict(global_option_values, self.name, value)
407 def setnodefault(self, loc):
415 def setcomment(self, comment, loc):
416 if (self.comment != ''):
417 print "%s: " % self.name
418 print "Attempt to modify comment at %s" % loc
420 self.comment = comment
422 def setexportable(self):
425 def setexported(self):
429 def setnoexport(self):
433 def setformat(self, fmt):
440 if (self.exportable):
444 def isexported(self):
445 return (self.exported and self.defined)
447 # def isdefined(self):
448 # return (self.defined)
457 def __init__(self, value):
463 # A configuration part
465 def __init__ (self, image, dir, parent, type, name):
467 print "partobj dir %s parent %s type %s" %(dir,parent,type)
471 self.registercode = []
472 # sibling is not a list.
478 self.instance = image.getpartinstance() + 1
479 self.flatten_name = flatten_name(type + "/" + name)
481 print "INSTANCE %d" % self.instance
482 image.setpartinstance(image.getpartinstance() + 1)
485 self.uses_options = {}
486 # chip initialization. If there is a chip.h in the
487 # directory, generate the structs etc. to
488 # initialize the code
490 if (os.path.exists(dir + "/" + "chip.h")):
495 print "add to parent"
497 # add current child as my sibling,
500 if (parent.children):
501 print "add %s (%d) as sibling" % (parent.children.dir, parent.children.instance)
502 self.siblings = parent.children
503 parent.children = self
507 def dumpme(self, lvl):
508 print "%d: type %s" % (lvl, self.type)
509 print "%d: instance %d" % (lvl, self.instance)
510 print "%d: dir %s" % (lvl,self.dir)
511 print "%d: flatten_name %s" % (lvl,self.flatten_name)
512 print "%d: parent %s" % (lvl,self.parent.type)
513 print "%d: parent dir %s" % (lvl,self.parent.dir)
515 print "%d: child %s" % (lvl, self.children.dir)
517 print "%d: siblings %s" % (lvl, self.siblings.dir)
518 print "%d: initcode " % lvl
519 for i in self.initcode:
521 print "%d: registercode " % lvl
522 for i in self.registercode:
526 def gencode(self, file):
527 if (self.chipconfig):
528 file.write("struct %s_config %s_config_%d" % (\
530 self.flatten_name , \
532 if (self.registercode):
533 file.write("\t= {\n")
534 for i in self.registercode:
535 file.write( "\t %s" % i)
540 file.write("struct chip dev%d = {\n" % self.instance)
541 file.write("/* %s %s */\n" % (self.type, self.dir))
542 #file.write(" .devfn = %d,\n" % self.devfn)
544 file.write(" .next = &dev%d,\n" % self.siblings.instance)
546 file.write(" .children = &dev%d,\n" % \
547 self.children.instance)
549 file.write(" .private = private%d,\n" % self.instance)
550 if (self.chipconfig):
551 # set the pointer to the structure for all this
553 file.write(" .control= &%s_control,\n" % \
555 # generate the pointer to the isntance
557 file.write(" .chip_config = (void *) &%s_config_%d,\n" %\
558 (self.flatten_name, self.instance ))
566 def addinit(self, code):
567 self.initcode.append(code)
569 def addregister(self, code):
571 self.registercode.append(code)
573 def usesoption(self, name):
574 global global_options
575 o = getdict(global_options, name)
577 fatal("Error: can't use undefined option %s" % name)
579 o1 = getdict(self.uses_options, name)
582 setdict(self.uses_options, name, o)
584 # Used to keep track of the current part
589 def push(self, part):
590 self.stack.append(part)
593 return self.stack.pop()
596 return self.stack[-1]
599 return (len(self.stack) == 0)
600 pstack = partsstack()
602 # -----------------------------------------------------------------------------
604 # -----------------------------------------------------------------------------
606 def getdict(dict, name):
607 if name not in dict.keys():
609 print 'Undefined:', name
611 v = dict.get(name, 0)
613 print "getdict %s returning %s" % (name, v)
616 def setdict(dict, name, value):
618 print "setdict sets %s to %s" % (name, value)
622 # to create an option, it has to not exist.
623 # When an option value is fetched, the fact that it was used is
625 # Legal things to do:
626 # set a default value, then set a real value before the option is used.
627 # set a value, try to set a default, default silently fails.
629 # use the value, then try to set the value
632 global global_options, global_options_by_order
633 o = getdict(global_options, name)
635 print "option %s already defined" % name
638 setdict(global_options, name, o)
639 global_options_by_order.append(name)
641 # option must be declared before being used in a part
642 # if we're not processing a part, then we must
643 # be at the top level where all options are available
644 def getoption(name, image):
645 global curpart, global_uses_options, global_option_values
647 o = getdict(curpart.uses_options, name)
649 o = getdict(global_options, name)
651 o = getdict(global_uses_options, name)
652 if (o == 0 or not o.defined):
653 error("Error: Option %s undefined (missing use command?)." % name)
657 v = o.getvalue(image, image.getvalues())
659 v = o.getvalue(image, global_option_values)
662 def setoption(name, value):
663 global loc, global_options, global_option_values, curimage, curpart
664 if (curpart and curpart.type != 'mainboard'):
665 fatal("Options may only be set in top-level and mainboard configuration files")
666 o = getdict(global_options, name)
668 fatal("Error: attempt to set nonexistent option %s" % name)
669 v = option_value(value)
671 o.setvalue(v, curimage.getvalues(), loc)
673 o.setvalue(v, global_option_values, loc)
675 def setdefault(name, value):
676 global loc, global_options
677 o = getdict(global_options, name)
681 print "setdefault: attempt to duplicate default for %s" % name
683 v = option_value(value)
686 def setnodefault(name):
687 global loc, global_options
688 o = getdict(global_options, name)
692 print "setdefault: attempt to duplicate default for %s" % name
696 def setcomment(name, value):
697 global loc, global_options
698 o = getdict(global_options, name)
700 fatal("setcomment: %s not here" % name)
701 o.setcomment(value, loc)
703 def setexported(name):
704 global global_options
705 o = getdict(global_options, name)
707 fatal("setexported: %s not here" % name)
710 def setnoexport(name):
711 global global_options
712 o = getdict(global_options, name)
714 fatal("setnoexport: %s not here" % name)
717 def setexportable(name):
718 global global_options
719 o = getdict(global_options, name)
721 fatal("setexportable: %s not here" % name)
724 def setformat(name, fmt):
725 global global_options
726 o = getdict(global_options, name)
728 fatal("setformat: %s not here" % name)
731 def getformated(name, image):
732 global global_options, global_option_values
733 o = getdict(global_options, name)
734 if (o == 0 or not o.defined):
735 fatal( "Error: Option %s undefined." % name)
738 v = o.getvalue(image, image.getvalues())
740 v = o.getvalue(image, global_option_values)
742 return (f % v.contents())
744 def isexported(name):
745 global global_options
746 o = getdict(global_options, name)
748 return o.isexported()
751 #def isdefined(name, part):
752 # global global_options
754 # o = getdict(part.uses_options, name)
756 # o = getdict(global_options, name)
758 # return o.isdefined()
761 def isset(name, part):
762 global global_uses_options
764 o = getdict(part.uses_options, name)
766 o = getdict(global_uses_options, name)
771 #def isused(name, part):
772 # global global_options
774 # o = getdict(part.uses_options, name)
776 # o = getdict(global_options, name)
781 def usesoption(name):
782 global curpart, global_options, global_uses_options
784 curpart.usesoption(name)
786 o = getdict(global_options, name)
788 fatal("Error: can't use undefined option %s" % name)
790 o1 = getdict(global_uses_options, name)
793 setdict(global_uses_options, name, o)
795 def validdef(name, defval):
796 global global_options
797 o = getdict(global_options, name)
799 fatal("validdef: %s not here" % name)
800 if ((defval & 1) != 1):
801 fatal("Error: must specify default value for option %s" % name)
802 if ((defval & 2) != 2):
803 fatal("Error: must specify export for option %s" % name)
804 if ((defval & 4) != 4):
805 fatal("Error: must specify comment for option %s" % name)
808 optionsfile = os.path.join(treetop, 'src', 'config', 'Options.lb')
809 loc.push_file(optionsfile)
810 if (not parse('options', open(optionsfile, 'r').read())):
811 fatal("Error: Could not parse file")
815 global curimage, curdir
817 curimage.setinitfile(treetop + '/src/' + path)
819 curimage.setinitfile(curdir + '/' + path)
820 print "Adding init file: %s" % path
822 # we do the crt0include as a dictionary, so that if needed we
823 # can trace who added what when. Also it makes the keys
825 def addcrt0include(path):
827 curimage.addinitinclude(0, path)
829 def addinitinclude(str, path):
831 curimage.addinitinclude(dequote(str), path)
833 def addldscript(path):
834 global curimage, curdir
836 fullpath = treetop + '/src/' + path
838 fullpath = curdir + '/' + path
840 print "fullpath :%s: curdir :%s: path :%s:" % (fullpath, curdir, path)
841 curimage.addldscript(fullpath)
845 curimage.setpayload(path)
846 # adduserdefine("PAYLOAD:=%s"%path)
848 # adddep('payload', path)
849 # addaction('payload', 'cp $< $@')
851 def startromimage(name):
852 global romimages, curimage, curpart, target_dir, target_name
853 print "Configuring ROMIMAGE %s" % name
854 curimage = romimage(name)
855 curimage.settargetdir(os.path.join(target_dir, name))
856 o = partobj(curimage, target_dir, 0, 'board', target_name)
858 o = getdict(romimages, name)
860 fatal("romimage %s previously defined" % name)
861 setdict(romimages, name, curimage)
870 def addbuildrom(size, roms):
872 print "Build ROM size %d" % size
873 b = buildrom(size, roms)
876 def addinitobject(object_name):
878 curimage.addinitobjectrule(object_name)
880 def addobject(object_name):
882 curimage.addobjectrule(object_name)
884 def adddriver(driver_name):
886 curimage.adddriverrule(driver_name)
889 global target_dir, target_name
890 print "Configuring TARGET %s" % name
892 target_dir = os.path.join(os.path.dirname(loc.file()), name)
893 if not os.path.isdir(target_dir):
894 print "Creating directory %s" % target_dir
895 os.makedirs(target_dir)
896 print "Will place Makefile, crt0.S, etc. in %s" % target_dir
899 def part(name, path, file):
900 global curimage, curpart, curdir, dirstack, pstack
901 dirstack.append(curdir)
902 curdir = os.path.join(treetop, 'src', name, path)
903 newpart = partobj(curimage, curdir, curpart, name, path)
904 print "Configuring PART %s, path %s" % (name,path)
906 print "PUSH part %s %s" % (name, curdir)
909 doconfigfile(curdir, file)
912 global curpart, curdir, dirstack, pstack
913 print "End PART %s" % curpart.type
914 # Warn if options are used without being set in this part
915 for i in curpart.uses_options.keys():
916 if (not isset(i, curpart)):
917 print "WARNING: Option %s using default value %s" % (i, getformated(i, curpart.image))
918 curpart = pstack.pop()
919 curdir = dirstack.pop()
921 # dodir is like part but there is no new part
922 def dodir(path, file):
923 global curimage, curpart, curdir, dirstack
924 # if the first char is '/', it is relative to treetop,
925 # else relative to curdir
926 # os.path.join screws up if the name starts with '/', sigh.
928 fullpath = treetop + '/src/' + path
930 fullpath = os.path.join(curdir, path)
932 print "DODIR: path %s, fullpath %s" % (path, fullpath)
933 print "DODIR: curdis %s treetop %s" % (curdir, treetop)
934 print "Configuring DIR %s" % os.path.join(path, file)
935 dirstack.append(curdir)
937 file = os.path.join(fullpath, file)
938 doconfigfile(fullpath, file)
939 curdir = dirstack.pop()
943 v = getoption(name, curimage)
949 curimage.addmakerule(id)
951 def adduserdefine(str):
953 curimage.adduserdefine(str)
955 def addaction(id, str):
957 curimage.addmakeaction(id, str)
961 curimage.addmakedepend(id, str)
963 # arch is 'different' ... darn it.
964 def set_arch(my_arch):
966 curimage.setarch(my_arch)
967 setoption('ARCH', my_arch)
968 part('arch', my_arch, 'Config.lb')
971 full_path = os.path.join(treetop, 'src/mainboard', path)
972 setoption('MAINBOARD', full_path)
973 vendor = re.sub("/.*", "", path)
974 part_number = re.sub("[^/]/", "", path)
975 setoption('MAINBOARD_VENDOR', vendor)
976 setoption('MAINBOARD_PART_NUMBER', part_number)
977 dodir('/config', 'Config.lb')
978 part('mainboard', path, 'Config.lb')
980 def doconfigfile(path, file):
981 filename = os.path.join(path, file)
982 loc.push_file(filename)
983 if (not parse('cfgfile', open(filename, 'r').read())):
984 fatal("Error: Could not parse file")
987 #=============================================================================
989 #=============================================================================
990 def ternary(val, yes, no):
992 print "ternary %s" % expr
994 print "expr %s a %d yes %d no %d"% (expr, a, yes, no)
997 print "Ternary returns %d" % yes
1001 print "Ternary returns %d" % no
1004 # atoi is in the python library, but not strtol? Weird!
1006 return eval('int(%s)' % name)
1009 """ Is the given string an integer?"""
1017 a = re.sub("^\"", "", str)
1018 a = re.sub("\"$", "", a)
1019 # highly un-intuitive, need four \!
1020 a = re.sub("\\\\\"", "\"", a)
1023 def flatten_name(str):
1024 a = re.sub("/", "_", str)
1027 # If the first part of <path> matches treetop, replace that part with "$(TOP)"
1029 if path[0:len(treetop)] == treetop:
1030 path = path[len(treetop):len(path)]
1031 if (path[0:1] == "/"):
1032 path = path[1:len(path)]
1033 path = "$(TOP)/" + path
1037 # to make if work without 2 passses, we use an old hack from SIMD, the
1038 # context bit. If the bit is 1, then ops get done, otherwise
1039 # ops don't get done. From the top level, context is always
1040 # 1. In an if, context depends on eval of the if condition
1046 # less general tokens should come first, otherwise they get matched
1048 token ACTION: 'action'
1049 token ADDACTION: 'addaction'
1050 token ALWAYS: 'always'
1052 token BUILDROM: 'buildrom'
1053 token COMMENT: 'comment'
1055 token DEFAULT: 'default'
1056 token DEFINE: 'define'
1057 token DEPENDS: 'depends'
1059 token DRIVER: 'driver'
1064 token EXPORT: 'export'
1065 token FORMAT: 'format'
1068 token INITOBJECT: 'initobject'
1069 token INITINCLUDE: 'initinclude'
1070 token LDSCRIPT: 'ldscript'
1071 token LOADOPTIONS: 'loadoptions'
1072 token MAINBOARD: 'mainboard'
1073 token MAINBOARDINIT: 'mainboardinit'
1074 token MAKEDEFINE: 'makedefine'
1075 token MAKERULE: 'makerule'
1076 token NEVER: 'never'
1078 token NORTHBRIDGE: 'northbridge'
1079 token OBJECT: 'object'
1080 token OPTION: 'option'
1081 token PAYLOAD: 'payload'
1083 token PRINT: 'print'
1084 token REGISTER: 'register'
1085 token ROMIMAGE: 'romimage'
1086 token SOUTHBRIDGE: 'southbridge'
1087 token SUPERIO: 'superio'
1088 token TARGET: 'target'
1091 token NUM: r'[0-9]+'
1092 token XNUM: r'0x[0-9a-fA-F]+'
1093 # Why is path separate? Because paths to resources have to at least
1094 # have a slash, we thinks
1095 token PATH: r'[a-zA-Z0-9_.][a-zA-Z0-9/_.]+[a-zA-Z0-9_.]+'
1096 # Dir's on the other hand are abitrary
1097 # this may all be stupid.
1098 token DIRPATH: r'[-a-zA-Z0-9_$()./]+'
1099 token ID: r'[a-zA-Z_.]+[a-zA-Z0-9_.]*'
1100 token DELEXPR: r'{([^}]+|\\.)*}'
1101 token STR: r'"([^\\"]+|\\.)*"'
1102 token RAWTEXT: r'.*'
1104 rule expr: logical {{ l = logical }}
1105 ( "&&" logical {{ l = l and logical }}
1106 | "||" logical {{ l = l or logical }}
1109 rule logical: factor {{ n = factor }}
1110 ( "[+]" factor {{ n = n+factor }}
1111 | "-" factor {{ n = n-factor }}
1114 rule factor: term {{ v = term }}
1115 ( "[*]" term {{ v = v*term }}
1116 | "/" term {{ v = v/term }}
1117 | "<<" term {{ v = v << term }}
1118 | ">=" term {{ v = (v < term)}}
1121 # A term is a number, variable, or an expression surrounded by parentheses
1122 rule term: NUM {{ return atoi(NUM) }}
1123 | XNUM {{ return tohex(XNUM) }}
1124 | ID {{ return lookup(ID) }}
1125 | unop {{ return unop }}
1126 | "\\(" expr "\\)" {{ return expr }}
1128 rule unop: "!" expr {{ return not(expr) }}
1130 rule partend<<C>>: (stmt<<C>>)* END {{ if (C): partpop()}}
1132 rule northbridge<<C>>:
1133 NORTHBRIDGE PATH {{ if (C): part('northbridge', PATH, 'Config.lb') }}
1136 rule superio<<C>>: SUPERIO PATH {{ if (C): part('superio', PATH, 'Config.lb') }}
1139 rule cpu<<C>>: CPU ID {{ if (C): part('cpu', ID, 'Config.lb') }}
1142 rule pmc<<C>>: PMC PATH {{ if (C): part('pmc', PATH, 'Config.lb') }}
1145 rule arch<<C>>: ARCH ID {{ if (C): set_arch(ID) }}
1148 rule southbridge<<C>>:
1149 SOUTHBRIDGE PATH {{ if (C): part('southbridge', PATH, 'Config.lb')}}
1152 rule mainboardinit<<C>>:
1153 MAINBOARDINIT DIRPATH {{ if (C): addcrt0include(DIRPATH)}}
1155 rule initinclude<<C>>:
1158 DIRPATH {{ if (C): addinitinclude(STR, DIRPATH)}}
1160 rule initobject<<C>>:
1161 INITOBJECT DIRPATH {{ if (C): addinitobject(DIRPATH)}}
1163 rule object<<C>>: OBJECT DIRPATH {{ if (C): addobject(DIRPATH)}}
1165 rule driver<<C>>: DRIVER DIRPATH {{ if (C): adddriver(DIRPATH)}}
1167 rule dir<<C>>: DIR DIRPATH {{ if (C): dodir(DIRPATH, 'Config.lb') }}
1169 rule ldscript<<C>>: LDSCRIPT DIRPATH {{ if (C): addldscript(DIRPATH) }}
1171 rule iif<<C>>: IF ID {{ c = lookup(ID) }}
1173 [ ELSE (stmt<<C and not c>>)* ]
1176 rule depsacts<<ID, C>>:
1177 ( DEPENDS STR {{ if (C): adddep(ID, STR) }}
1178 | ACTION STR {{ if (C): addaction(ID, STR) }}
1181 rule makerule<<C>>: MAKERULE DIRPATH {{ if (C): addrule(DIRPATH) }}
1182 depsacts<<DIRPATH, C>>
1185 rule makedefine<<C>>:
1186 MAKEDEFINE RAWTEXT {{ if (C): adduserdefine(RAWTEXT) }}
1188 rule addaction<<C>>:
1189 ADDACTION ID STR {{ if (C): addaction(ID, STR) }}
1191 rule init<<C>>: INIT DIRPATH {{ if (C): addinit(DIRPATH) }}
1193 rule register<<C>>: REGISTER STR {{ if (C): curpart.addregister(STR) }}
1195 rule prtval: expr {{ return str(expr) }}
1196 | STR {{ return STR }}
1198 rule prtlist: prtval {{ el = "%(" + prtval }}
1199 ( "," prtval {{ el = el + "," + prtval }}
1200 )* {{ return el + ")" }}
1202 rule prtstmt<<C>>: PRINT STR {{ val = STR }}
1203 [ "," prtlist {{ val = val + prtlist }}
1204 ] {{ if (C): print eval(val) }}
1206 rule stmt<<C>>: arch<<C>> {{ return arch}}
1207 | addaction<<C>> {{ return addaction }}
1208 | cpu<<C>> {{ return cpu}}
1209 | dir<<C>> {{ return dir}}
1210 | driver<<C>> {{ return driver }}
1211 | iif<<C>> {{ return iif }}
1212 | init<<C>> {{ return init }}
1213 | initinclude<<C>> {{ return initinclude }}
1214 | initobject<<C>> {{ return initobject }}
1215 | ldscript<<C>> {{ return ldscript}}
1216 | mainboardinit<<C>> {{ return mainboardinit }}
1217 | makedefine<<C>> {{ return makedefine }}
1218 | makerule<<C>> {{ return makerule }}
1219 | northbridge<<C>> {{ return northbridge }}
1220 | object<<C>> {{ return object }}
1221 | option<<C>> {{ return option }}
1222 | pmc<<C>> {{ return pmc}}
1223 | prtstmt<<C>> {{ return prtstmt}}
1224 | register<<C>> {{ return register}}
1225 | southbridge<<C>> {{ return southbridge }}
1226 | superio<<C>> {{ return superio }}
1228 # ENTRY for parsing Config.lb file
1229 rule cfgfile: (uses<<1>>)*
1233 rule usesid<<C>>: ID {{ if (C): usesoption(ID) }}
1235 rule uses<<C>>: USES (usesid<<C>>)+
1237 rule value: STR {{ return dequote(STR) }}
1238 | expr {{ return expr }}
1239 | DELEXPR {{ return DELEXPR }}
1241 rule option<<C>>: OPTION ID EQ value {{ if (C): setoption(ID, value) }}
1243 rule opif<<C>>: IF ID {{ c = lookup(ID) }}
1244 (opstmt<<C and c>>)*
1245 [ ELSE (opstmt<<C and not c>>)* ]
1248 rule opstmt<<C>>: option<<C>>
1252 rule payload<<C>>: PAYLOAD DIRPATH {{ if (C): payload(DIRPATH) }}
1254 rule mainboard<<C>>:
1255 MAINBOARD PATH {{ if (C): mainboard(PATH) }}
1257 rule romif<<C>>: IF ID {{ c = lookup(ID) }}
1258 (romstmt<<C and c>>)*
1259 [ ELSE (romstmt<<C and not c>>)* ]
1262 rule romstmt<<C>>: romif<<C>>
1267 rule romimage: ROMIMAGE STR {{ startromimage(dequote(STR)) }}
1269 END {{ endromimage() }}
1271 rule roms: STR {{ s = '(' + STR }}
1272 ( STR {{ s = s + "," + STR }}
1273 )* {{ return eval(s + ')') }}
1275 rule buildrom: BUILDROM expr roms {{ addbuildrom(expr, roms) }}
1277 rule romstmts: romimage
1281 # ENTRY for parsing root part
1282 rule board: LOADOPTIONS {{ loadoptions() }}
1283 TARGET DIRPATH {{ target(DIRPATH) }}
1288 # ENTRY for parsing a delayed value
1289 rule delexpr: "{" expr "}" EOF {{ return expr }}
1291 rule defstmts<<ID>>: {{ d = 0 }}
1293 ( value {{ setdefault(ID, value) }}
1294 | NONE {{ setnodefault(ID) }}
1296 | FORMAT STR {{ setformat(ID, dequote(STR)) }}
1298 ( ALWAYS {{ setexported(ID) }}
1299 | USED {{ setexportable(ID) }}
1300 | NEVER {{ setnoexport(ID) }}
1302 | COMMENT STR {{ setcomment(ID, dequote(STR)); d = d | 4 }}
1305 rule define: DEFINE ID {{ newoption(ID) }}
1306 defstmts<<ID>> END {{ validdef(ID, defstmts) }}
1308 # ENTRY for parsing Options.lb file
1309 rule options: (define)* EOF {{ return 1 }}
1312 #=============================================================================
1314 #=============================================================================
1315 def writemakefileheader(file, fname):
1316 file.write("# File: %s\n" % fname)
1317 file.write("# This file was generated by '%s %s %s'\n\n"
1318 % (sys.argv[0], sys.argv[1], sys.argv[2]))
1320 def writemakefilesettings(path):
1321 global treetop, target_dir
1322 # Write Makefile.settings to seperate the settings
1323 # from the actual makefile creation
1324 # In practice you need to rerun NLBConfig.py to change
1325 # these but in theory you shouldn't need to.
1327 filename = os.path.join(path, "Makefile.settings")
1328 print "Creating", filename
1329 file = open(filename, 'w+')
1330 writemakefileheader(file, filename)
1331 file.write("TOP:=%s\n" % (treetop))
1332 file.write("TARGET_DIR:=%s\n" % target_dir)
1333 # for i in global_options_by_order:
1334 # if (isexported(i, 0)):
1335 # file.write("export %s:=%s\n" % (i, getformated(i, 0)))
1336 # file.write("export VARIABLES := ")
1337 # for i in global_options.keys():
1338 # if (isexported(i, 0)):
1339 # file.write("%s " % i)
1343 def writeimagesettings(image):
1345 global global_options_by_order
1346 # Write Makefile.settings to seperate the settings
1347 # from the actual makefile creation
1348 # In practice you need to rerun NLBConfig.py to change
1349 # these but in theory you shouldn't need to.
1351 filename = os.path.join(image.gettargetdir(), "Makefile.settings")
1352 print "Creating", filename
1353 file = open(filename, 'w+')
1354 writemakefileheader(file, filename)
1355 file.write("TOP:=%s\n" % (treetop))
1356 file.write("TARGET_DIR:=%s\n" % (image.gettargetdir()))
1357 for i in global_options_by_order:
1359 file.write("export %s:=%s\n" % (i, getformated(i, image)))
1360 file.write("export VARIABLES := ")
1361 for i in global_options_by_order:
1363 file.write("%s " % i)
1367 # write the romimage makefile
1368 # let's try the Makefile
1369 # first, dump all the -D stuff
1371 def writeimagemakefile(image):
1372 makefilepath = os.path.join(image.gettargetdir(), "Makefile")
1373 print "Creating", makefilepath
1374 file = open(makefilepath, 'w+')
1375 writemakefileheader(file, makefilepath)
1377 #file.write("include cpuflags\n")
1378 # Putting "include cpuflags" in the Makefile has the problem that the
1379 # cpuflags file would be generated _after_ we want to include it.
1380 # Instead, let make do the work of computing CPUFLAGS:
1381 file.write("# Get the value of TOP, VARIABLES, and several other variables.\n")
1382 file.write("include Makefile.settings\n\n")
1383 file.write("# Function to create an item like -Di586 or -DMAX_CPUS='1' or -Ui686\n")
1384 file.write("D_item = $(if $(subst undefined,,$(origin $1)),-D$1$(if $($1),='$($1)',),-U$1)\n\n")
1385 file.write("# Compute the value of CPUFLAGS here during make's first pass.\n")
1386 file.write("CPUFLAGS := $(foreach _var_,$(VARIABLES),$(call D_item,$(_var_)))\n\n")
1388 for i in image.getuserdefines():
1389 file.write("%s\n" %i)
1393 file.write("all: linuxbios.rom")
1394 # print out all the object dependencies
1395 file.write("\n# object dependencies (objectrules:)\n")
1396 file.write("INIT-OBJECTS :=\n")
1397 file.write("OBJECTS :=\n")
1398 file.write("DRIVER :=\n")
1399 file.write("\nSOURCES :=\n")
1400 for irule in image.getinitobjectrules().keys():
1401 init = image.getinitobjectrule(irule)
1404 file.write("INIT-OBJECTS += %s\n" % (i_name))
1405 file.write("SOURCES += %s\n" % (i_source))
1407 for objrule in image.getobjectrules().keys():
1408 obj = image.getobjectrule(objrule)
1411 file.write("OBJECTS-1 += %s\n" % (obj_name))
1412 file.write("SOURCES += %s\n" % (obj_source))
1414 for driverrule in image.getdriverrules().keys():
1415 driver = image.getdriverrule(driverrule)
1416 obj_name = driver[0]
1417 obj_source = driver[1]
1418 file.write("DRIVER += %s\n" % (obj_name))
1419 file.write("SOURCES += %s\n" % (obj_source))
1421 # Print out all ldscript.ld dependencies.
1422 file.write("\n# ldscript.ld dependencies:\n")
1423 file.write("LDSUBSCRIPTS-1 := \n" )
1424 for script in image.getldscripts():
1425 file.write("LDSUBSCRIPTS-1 += %s\n" % topify(script))
1427 # Print out the dependencies for crt0_includes.h
1428 file.write("\n# Dependencies for crt0_includes.h\n")
1429 file.write("CRT0_INCLUDES:=\n")
1430 for inc in image.getinitincludes().keys():
1431 if (local_path.match(inc)):
1432 file.write("CRT0_INCLUDES += %s\n" % inc)
1434 file.write("CRT0_INCLUDES += $(TOP)/src/%s\n" % inc)
1436 # Print out the user defines.
1437 file.write("\n# userdefines:\n")
1438 #for udef in image.userdefines:
1439 #file.write("%s\n" % udef)
1441 # Print out the base rules.
1442 # Need to have a rule that counts on 'all'.
1443 file.write("\n# mainrulelist:")
1444 #file.write("\nmainrule: %s\n" % image.mainrulelist)
1446 # Print out any user rules.
1447 file.write("\n# From makerule or docipl commands:\n")
1448 # Old way (hash order): for target in makebaserules.keys():
1449 # New way (config file order):
1450 #for target in image.makerule_targets:
1451 #image.makebaserules[target].write(file)
1453 file.write("\n# objectrules:\n")
1454 for objrule in image.getobjectrules().keys():
1455 obj = image.getobjectrule(objrule)
1456 source = topify(obj[1])
1457 file.write("%s: %s\n" % (obj[0], source))
1458 file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
1459 #file.write("%s\n" % objrule[2])
1461 for driverrule in image.getdriverrules().keys():
1462 driver = image.getdriverrule(driverrule)
1463 source = topify(driver[1])
1464 file.write("%s: %s\n" % (driver[0], source))
1465 file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
1466 #file.write("%s\n" % objrule[2])
1468 # Print out the rules that will make cause the files
1469 # generated by NLBConfig.py to be remade if any dependencies change.
1471 file.write("\n# Remember the automatically generated files\n")
1472 file.write("GENERATED:=\n")
1473 for genfile in [ 'Makefile',
1476 'LinuxBIOSDoc.config' ]:
1477 file.write("GENERATED += %s\n" % genfile)
1478 file.write("GENERATED += %s\n" % image.getincludefilename())
1480 #file.write("\n# Remake Makefile (and the other files generated by\n")
1481 #file.write("# NLBConfig.py) if any config dependencies change.\n")
1483 #for cfile in image.config_file_list:
1484 # file.write("$(GENERATED): %s\n" % topify(cfile))
1486 #for depfile in [ '%s' % top_config_file, # This a duplicate, remove?
1487 # '$(TOP)/util/config/NLBConfig.py',
1488 # '$(TOP)/src/arch/$(ARCH)/config/make.base' ]:
1489 # file.write("$(GENERATED): %s\n" % depfile)
1491 #file.write("$(GENERATED):\n")
1492 #file.write("\tpython $(TOP)/util/config/NLBConfig.py %s $(TOP)\n"
1493 # % top_config_file)
1495 keys = image.getroot().uses_options.keys()
1497 file.write("\necho:\n")
1499 file.write("\t@echo %s='$(%s)'\n"% (key,key))
1501 for i in image.getmakerules().keys():
1502 m = image.getmakerule(i)
1503 file.write("%s: " %i)
1504 for i in m.dependency:
1505 file.write("%s " % i)
1508 file.write("\t%s\n" % i)
1512 def writemakefile(path):
1513 makefilepath = os.path.join(path, "Makefile")
1514 print "Creating", makefilepath
1515 file = open(makefilepath, 'w+')
1516 writemakefileheader(file, makefilepath)
1520 for i in romimages.keys():
1521 file.write("%s-rom " % i)
1523 for i in romimages.keys():
1524 o = getdict(romimages, i)
1525 file.write("%s-rom:\n" % o.getname())
1526 file.write("\tif (cd %s; \\\n" % o.getname())
1527 file.write("\t\tmake linuxbios.rom)\\\n");
1528 file.write("\tthen true; else exit 1; fi;\n\n")
1531 def writeinitincludes(image):
1532 global include_pattern
1533 filepath = os.path.join(image.gettargetdir(), image.getincludefilename())
1534 print "Creating", filepath
1535 outfile = open(filepath, 'w+')
1536 if (image.newformat()):
1537 infile = open(image.getinitfile(), 'r')
1539 line = infile.readline()
1541 p = include_pattern.match(line)
1543 for i in image.getinitincludes().keys():
1544 inc = image.getinitinclude(i)
1545 if (inc.getstring() == p.group(1)):
1546 outfile.write("#include \"%s\"\n" % inc.getpath())
1548 outfile.write(line);
1549 line = infile.readline()
1553 for i in image.getinitincludes().keys():
1554 outfile.write("#include <%s>\n" % i)
1557 def writeldoptions(image):
1558 # Write Makefile.settings to seperate the settings
1559 # from the actual makefile creation
1560 # In practice you need to rerun NLBConfig.py to change
1561 # these but in theory you shouldn't need to.
1563 filename = os.path.join(image.gettargetdir(), "ldoptions")
1564 print "Creating", filename
1565 file = open(filename, 'w+')
1566 for i in global_options.keys():
1567 if (isexported(i) and IsInt(getoption(i, image))):
1568 file.write("%s = %s;\n" % (i, getformated(i, image)))
1571 # Add any run-time checks to verify that parsing the configuration
1573 def verifyparse(image):
1574 if (image.newformat() and image.getinitfile() == ''):
1575 fatal("An init file must be specified")
1577 def dumptree(part, lvl):
1579 print "DUMPTREE ME is"
1581 # dump the siblings -- actually are there any? not sure
1584 print "DUMPTREE SIBLINGS are"
1591 print "DUMPTREE KIDS are"
1592 #for kid in part.children:
1594 dumptree(part.children, lvl+1)
1596 print "DONE DUMPTREE"
1598 def gencode(part, file):
1600 print "GENCODE ME is"
1602 # dump the siblings -- actually are there any? not sure
1605 print "GENCODE SIBLINGS are"
1611 print "GENCODE KIDS are"
1612 #for kid in part.children:
1614 gencode(part.children, file)
1616 print "DONE GENCODE"
1618 #=============================================================================
1620 #=============================================================================
1621 if __name__=='__main__':
1622 from sys import argv
1624 print 'Args: <file> <path to linuxbios>'
1627 top_config_file = os.path.abspath(sys.argv[1])
1629 treetop = os.path.abspath(sys.argv[2])
1631 # Now read in the customizing script...
1632 loc.push_file(argv[1])
1633 if (not parse('board', open(argv[1], 'r').read())):
1634 fatal("Error: Could not parse file")
1636 for r in romimages.keys():
1637 verifyparse(getdict(romimages, r))
1639 # no longer need to check if an options has been used
1642 for r in romimages.keys():
1643 image = getdict(romimages, r)
1646 print "DEVICE TREE:"
1647 dumptree(image.getroot(), 0)
1649 img_dir = image.gettargetdir()
1650 if not os.path.isdir(img_dir):
1651 print "Creating directory %s" % img_dir
1652 os.makedirs(img_dir)
1653 filename = os.path.join(img_dir, "chips.c")
1654 print "Creating", filename
1655 file = open(filename, 'w+')
1656 # gen all the forward references
1659 file.write("struct chip ")
1660 while (i <= image.getpartinstance()):
1661 file.write("cdev%d "% i)
1664 gencode(image.getroot(), file)
1669 for i in image.getinitincludes().keys():
1670 print "crt0include file %s" % (i)
1671 for i in image.getdriverrules().keys():
1672 print "driver file %s" % (i)
1673 for i in image.getldscripts():
1674 print "ldscript file %s" % (i)
1675 for i in image.getmakerules().keys():
1676 m = image.getmakerule(i)
1677 print " makerule %s dep %s act %s" % (i, m.dependency, m.actions)
1679 writeimagesettings(image)
1680 writeinitincludes(image)
1681 writeimagemakefile(image)
1682 writeldoptions(image)
1684 writemakefilesettings(target_dir)
1685 writemakefile(target_dir)