From 07d72dcfa2d92ad0cc6db19a683ac800ba843fff Mon Sep 17 00:00:00 2001 From: Greg Watson Date: Thu, 17 Jul 2003 22:25:53 +0000 Subject: added romimage support git-svn-id: svn://svn.coreboot.org/coreboot/trunk@978 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1 --- util/newconfig/config.g | 1596 +++++++++++++++++++++++++++-------------------- 1 file changed, 926 insertions(+), 670 deletions(-) (limited to 'util/newconfig/config.g') diff --git a/util/newconfig/config.g b/util/newconfig/config.g index 3cb2a4a0ed..82e9e99c7d 100644 --- a/util/newconfig/config.g +++ b/util/newconfig/config.g @@ -7,44 +7,20 @@ debug = 0 warnings = 0 errors = 0 -arch = '' -ldscriptbase = '' -payloadfile = '' -initfile = '' - -# Key is the rule name. Value is a mkrule object. -makebaserules = {} - -# List of targets in the order defined by makerule commands. -#makerule_targets = {} - -treetop = '' target_dir = '' - -#sources = {} -objectrules = {} -initobjectrules = {} -# make these a hash so they will be unique. -driverrules = {} -ldscripts = [] -userdefines = [] +target_name = '' +treetop = '' +global_options = {} +global_options_by_order = [] +global_option_values = {} +global_uses_options = {} +romimages = {} +buildroms = [] +curimage = 0 curpart = 0 -root = 0 - -globalvars = {} # We will globals here -parts = {} - -options = {} -# options in order defined. These will be unique due to use of hash -# for options. -options_by_order = [] -crt0includes = [] -initincludes = {} -useinitincludes = 0 # transitional -partinstance = 0 curdir = '' dirstack = [] -config_file_list = [] +alloptions = 0 # override uses at top level local_path = re.compile(r'^\.') include_pattern = re.compile(r'%%([^%]+)%%') @@ -53,6 +29,8 @@ include_pattern = re.compile(r'%%([^%]+)%%') # Error Handling # ----------------------------------------------------------------------------- +# Used to keep track of our current location while parsing +# configuration files class location: class place: def __init__(self, file, line, command): @@ -85,6 +63,262 @@ class location: return self.stack[-1].at() loc = location() +# Print error message +def error(string): + global errors, loc + errors = errors + 1 + size = len(loc.stack) + i = 0 + while(i < size -1): + print loc.stack[i].at() + i = i + 1 + print "%s: %s"% (loc.at(), string) + +# Print error message and exit +def fatal(string): + error(string) + exitiferrors() + +# Print warning message +def warning(string): + global warnings, loc + warnings = warnings + 1 + print "===> Warning:" + size = len(loc.stack) + i = 0 + while(i < size -1): + print loc.stack[i].at() + i = i + 1 + print "%s: %s"% (loc.at(), string) + +# Exit parser if an error has been encountered +def exitiferrors(): + if (errors != 0): + sys.exit(1) + +# ----------------------------------------------------------------------------- +# Main classes +# ----------------------------------------------------------------------------- + +# A rom image is the ultimate goal of linuxbios +class romimage: + def __init__ (self, name): + self.name = name + self.arch = '' + self.payload = '' + self.initfile = '' + self.makebaserules = {} + self.objectrules = {} + self.initobjectrules = {} + self.driverrules = {} + self.ldscripts = [] + self.userdefines = [] + self.initincludes = {} + self.useinitincludes = 0 # transitional + self.partinstance = 0 + self.root = 0 + self.target_dir = '' + self.values = {} + + def getname(self): + return self.name + + def setarch(self, arch): + self.arch = arch + + def setpayload(self, payload): + self.payload = payload + + def setinitfile(self, initfile): + self.initfile = initfile + + def getinitfile(self): + return self.initfile + + def addmakerule(self, id): + o = getdict(self.makebaserules, id) + if (o): + print "Warning, rule %s previously defined" % id + o = makerule(id) + setdict(self.makebaserules, id, o) + + def getmakerules(self): + return self.makebaserules + + def getmakerule(self, id): + o = getdict(self.makebaserules, id) + if (o): + return o + fatal("No such make rule \"%s\"" % id); + + def addmakeaction(self, id, str): + o = getdict(self.makebaserules, id) + if (o): + a = dequote(str) + o.addaction(a) + return + fatal("No such rule \"%s\" for addmakeaction" % id); + + def addmakedepend(self, id, str): + o = getdict(self.makebaserules, id) + if (o): + a = dequote(str) + o.adddependency(a) + return + fatal("No such rule \"%s\" for addmakedepend" % id); + + # this is called with an an object name. + # the easiest thing to do is add this object to the current + # component. + # such kludgery. If the name starts with '.' then make the + # dependency be on ./thing.x gag me. + def addobjectdriver(self, dict, object_name): + global curdir + suffix = object_name[-2:] + if (suffix == '.o'): + suffix = '.c' + base = object_name[:-2] + if (object_name[0] == '.'): + source = base + suffix + else: + source = os.path.join(curdir, base + suffix) + object = base + '.o' + if (debug): + print "add object %s source %s" % (object_name, source) + l = getdict(dict, base) + if (l): + print "Warning, object/driver %s previously defined" % base + setdict(dict, base, [object, source]) + + def addinitobjectrule(self, name): + self.addobjectdriver(self.initobjectrules, name) + + def addobjectrule(self, name): + self.addobjectdriver(self.objectrules, name) + + def adddriverrule(self, name): + self.addobjectdriver(self.driverrules, name) + + def getinitobjectrules(self): + return self.initobjectrules + + def getinitobjectrule(self, name): + o = getdict(self.initobjectrules, name) + if (o): + return o + fatal("No such init object rule \"%s\"" % name); + + def getobjectrules(self): + return self.objectrules + + def getobjectrule(self, name): + o = getdict(self.objectrules, name) + if (o): + return o + fatal("No such object rule \"%s\"" % name); + + def getdriverrules(self): + return self.driverrules + + def getdriverrule(self, name): + o = getdict(self.driverrules, name) + if (o): + return o + fatal("No such driver rule \"%s\"" % name); + + def addldscript(self, path): + self.ldscripts.append(path) + + def getldscripts(self): + return self.ldscripts + + def adduserdefine(self, str): + self.userdefines.append(str) + + def getuserdefines(self): + return self.userdefines + + def addinitinclude(self, str, path): + if (str != 0): + self.useinitincludes = 1 + + if (debug > 2): + print "ADDCRT0: %s -> %s" % str, path + o = getdict(self.initincludes, path) + if (o): + print "Warning, init include for %s previously defined" % path + o = initinclude(str, path) + setdict(self.initincludes, path, o) + + def getinitincludes(self): + return self.initincludes + + def getinitinclude(self, path): + o = getdict(self.initincludes, path) + if (o): + return o + fatal("No such init include \"%s\"" % path); + + def getincludefilename(self): + if (self.useinitincludes): + return "crt0.S" + else: + return "crt0_include.h" + + def newformat(self): + return self.useinitincludes + + def setpartinstance(self, val): + self.partinstance = val + + def getpartinstance(self): + return self.partinstance + + def setroot(self, part): + self.root = part + + def getroot(self): + return self.root + + def settargetdir(self, path): + self.targetdir = path + + def gettargetdir(self): + return self.targetdir + + def getvalues(self): + return self.values + +# A buildrom statement +class buildrom: + def __init__ (self, size, roms): + self.size = size + self.roms = roms + +# this is called with an an object name. +# the easiest thing to do is add this object to the current +# component. +# such kludgery. If the name starts with '.' then make the +# dependency be on ./thing.x gag me. +def addobjectdriver(dict, object_name): + global curimage, curdir + suffix = object_name[-2:] + if (suffix == '.o'): + suffix = '.c' + base = object_name[:-2] + if (object_name[0] == '.'): + source = base + suffix + else: + source = os.path.join(curdir, base + suffix) + object = base + '.o' + if (debug): + print "add object %s source %s" % (object_name, source) + l = getdict(dict, base) + if (l): + print "Warning, object/driver %s previously defined" % base + setdict(dict, base, [object, source]) + +# include file for initialization code class initinclude: def __init__ (self, str, path): self.string = str @@ -96,6 +330,7 @@ class initinclude: def getpath(self): return self.path +# Rule to be included in Makefile class makerule: def __init__ (self, target): self.target = target @@ -117,11 +352,12 @@ class makerule: def gaction(self): return self.actions +# Configuration option class option: def __init__ (self, name): self.name = name # name of option self.loc = 0 # current location - self.value = 0 # option value + #self.value = 0 # option value self.set = 0 # option has been set self.used = 0 # option has been set self.default = 0 # option has default value (otherwise @@ -132,33 +368,32 @@ class option: self.defined = 0 # option has a value self.format = '%s' # option print format - def setvalue(self, value, loc): - if (self.set): - fatal("Error: option %s already set" % self.name) + def setvalue(self, value, values, loc): + #if (self.set): + # fatal("Error: option %s already set" % self.name) self.set = 1 - self.value = value self.defined = 1 self.loc = loc - - def getvalue(self, part): - global curpart - if (not (type(self.value) is str)): - return self.value - if (self.value == '' or self.value[0] != '{'): - return self.value - # save curpart so we can evaluate expression - # in context of part - s = curpart - curpart = part - v = parse('delexpr', self.value) + #self.value = value + setdict(values, self.name, value) + + def getvalue(self, values): + #global curpart + v = getdict(values, self.name) + if (not (type(v) is str)): + return v + if (v == '' or v[0] != '{'): + return v + v = parse('delexpr', v) # TODO: need to check for parse errors! - curpart = s return v def setdefault(self, value, loc): + global global_option_values if (self.default): fatal("Error: default value for %s already set" % self.name) - self.value = value + #self.value = value + setdict(global_option_values, self.name, value) self.defined = 1 self.default = 1 self.loc = loc @@ -171,12 +406,12 @@ class option: def where(self): return self.loc - def setcomment(self, value, loc): + def setcomment(self, comment, loc): if (self.comment != ''): print "%s: " % self.name print "Attempt to modify comment at %s" % loc return - self.comment = value + self.comment = comment def setexportable(self): self.exportable = 1 @@ -203,20 +438,21 @@ class option: def isexported(self): return (self.exported and self.defined) - def isdefined(self): - return (self.defined) +# def isdefined(self): +# return (self.defined) def isset(self): return (self.set) - def isused(self): - return (self.used) +# def isused(self): +# return (self.used) +# A configuration part class partobj: - def __init__ (self, dir, parent, type, name): - global partinstance + def __init__ (self, image, dir, parent, type, name): if (debug): print "partobj dir %s parent %s type %s" %(dir,parent,type) + self.image = image self.children = 0 self.initcode = [] self.registercode = [] @@ -226,14 +462,14 @@ class partobj: self.objects = [] self.dir = dir self.irq = 0 - self.instance = partinstance + 1 + self.instance = image.getpartinstance() + 1 self.flatten_name = flatten_name(type + "/" + name) if (debug): print "INSTANCE %d" % self.instance - partinstance = partinstance + 1 + image.setpartinstance(image.getpartinstance() + 1) self.devfn = 0 self.private = 0 - self.options = {} + self.uses_options = {} # chip initialization. If there is a chip.h in the # directory, generate the structs etc. to # initialize the code @@ -249,7 +485,7 @@ class partobj: # me as the child. if (debug): if (parent.children): - print "add %s (%d) as isbling" % (parent.children.dir, parent.children.instance) + print "add %s (%d) as sibling" % (parent.children.dir, parent.children.instance) self.siblings = parent.children parent.children = self else: @@ -322,15 +558,17 @@ class partobj: self.registercode.append(code) def usesoption(self, name): - o = getvalue(options, name) + global global_options + o = getdict(global_options, name) if (o == 0): fatal("Error: can't use undefined option %s" % name) o.setused() - o1 = getvalue(self.options, name) + o1 = getdict(self.uses_options, name) if (o1): return - setvalue(self.options, name, o) + setdict(self.uses_options, name, o) +# Used to keep track of the current part class partsstack: def __init__ (self): self.stack = [] @@ -343,57 +581,28 @@ class partsstack: def tos(self): return self.stack[-1] -pstack = partsstack() - -def error(string): - global errors, loc - errors = errors + 1 - size = len(loc.stack) - i = 0 - while(i < size -1): - print loc.stack[i].at() - i = i + 1 - print "%s: %s"% (loc.at(), string) - -def exitiferrors(): - if (errors != 0): - sys.exit(1) - -def fatal(string): - error(string) - exitiferrors() - -def warning(string): - global warnings, loc - warnings = warnings + 1 - print "===> Warning:" - size = len(loc.stack) - i = 0 - while(i < size -1): - print loc.stack[i].at() - i = i + 1 - print "%s: %s"% (loc.at(), string) + def empty(self): + return (len(self.stack) == 0) +pstack = partsstack() # ----------------------------------------------------------------------------- # statements # ----------------------------------------------------------------------------- -def getvalue(dict, name): +def getdict(dict, name): if name not in dict.keys(): if (debug >1): print 'Undefined:', name return 0 v = dict.get(name, 0) if (debug > 1): - print "getvalue %s returning %s" % (name, v) + print "getdict %s returning %s" % (name, v) return v -def setvalue(dict, name, value): - if name in dict.keys(): - print "Warning, %s previously defined" % name +def setdict(dict, name, value): if (debug > 1): - print "setvalue sets %s to %s" % (name, value) + print "setdict sets %s to %s" % (name, value) dict[name] = value # options. @@ -407,49 +616,49 @@ def setvalue(dict, name, value): # use the value, then try to set the value def newoption(name): - o = getvalue(options, name) + global global_options, global_options_by_order + o = getdict(global_options, name) if (o): print "option %s already defined" % name sys.exit(1) o = option(name) - setvalue(options, name, o) - options_by_order.append(name) + setdict(global_options, name, o) + global_options_by_order.append(name) # option must be declared before being used in a part # if we're not processing a part, then we must # be at the top level where all options are available def getoption(name, part): - global options + global global_uses_options, global_option_values if (part): - o = getvalue(part.options, name) + o = getdict(part.uses_options, name) + elif (alloptions): + o = getdict(global_options, name) else: - o = getvalue(options, name) + o = getdict(global_uses_options, name) if (o == 0 or not o.defined): error("Error: Option %s undefined (missing use command?)." % name) return - v = o.getvalue(part) - if (debug > 2): - print "getoption returns %s" % v - print "%s" % o.where() + v = 0 + if (part): + v = o.getvalue(part.image.getvalues()) + if (v == 0): + v = o.getvalue(global_option_values) return v -# setoptionstmt only allowed at top level -def setoptionstmt(name, value): - global curpart - if (curpart != root): - fatal("Error: options can only be set in target configuration file") - setoption(name, value) - def setoption(name, value): - global loc - o = getvalue(options, name) + global loc, global_options, global_option_values, curimage + o = getdict(global_options, name) if (o == 0): - fatal("Error: attempt set nonexistent option %s" % name) - o.setvalue(value, loc) + fatal("Error: attempt to set nonexistent option %s" % name) + if (curimage): + o.setvalue(value, curimage.getvalues(), loc) + else: + o.setvalue(value, global_option_values, loc) def setdefault(name, value): - global loc - o = getvalue(options, name) + global loc, global_options + o = getdict(global_options, name) if (not o): return if (o.default): @@ -458,8 +667,8 @@ def setdefault(name, value): o.setdefault(value, loc) def setnodefault(name): - global loc - o = getvalue(options, name) + global loc, global_options + o = getdict(global_options, name) if (not o): return if (o.default): @@ -468,89 +677,107 @@ def setnodefault(name): o.setnodefault(loc) def setcomment(name, value): - o = getvalue(options, name) + global loc, global_options + o = getdict(global_options, name) if (not o): fatal("setcomment: %s not here" % name) o.setcomment(value, loc) def setexported(name): - o = getvalue(options, name) + global global_options + o = getdict(global_options, name) if (not o): fatal("setexported: %s not here" % name) o.setexported() def setnoexport(name): - o = getvalue(options, name) + global global_options + o = getdict(global_options, name) if (not o): fatal("setnoexport: %s not here" % name) o.setnoexport() def setexportable(name): - o = getvalue(options, name) + global global_options + o = getdict(global_options, name) if (not o): fatal("setexportable: %s not here" % name) o.setexportable() def setformat(name, fmt): - o = getvalue(options, name) + global global_options + o = getdict(global_options, name) if (not o): fatal("setformat: %s not here" % name) o.setformat(fmt) -def getformated(name, part): - global options - if (part): - o = getvalue(part.options, name) - else: - o = getvalue(options, name) +def getformated(name, values): + global global_options, global_option_values + o = getdict(global_options, name) if (o == 0 or not o.defined): - fatal( "Error: Option %s undefined (missing use command?)." % name) - v = o.getvalue(part) + fatal( "Error: Option %s undefined." % name) + v = 0 + if (values): + v = o.getvalue(values) + if (v == 0): + v = o.getvalue(global_option_values) f = o.getformat() return (f % v) -def isexported(name, part): - if (part): - o = getvalue(part.options, name) - else: - o = getvalue(options, name) +def isexported(name): + global global_options + o = getdict(global_options, name) if (o): return o.isexported() return 0 -def isdefined(name, part): - if (part): - o = getvalue(part.options, name) - else: - o = getvalue(options, name) - if (o): - return o.isdefined() - return 0 +#def isdefined(name, part): +# global global_options +# if (part): +# o = getdict(part.uses_options, name) +# else: +# o = getdict(global_options, name) +# if (o): +# return o.isdefined() +# return 0 def isset(name, part): + global global_uses_options if (part): - o = getvalue(part.options, name) + o = getdict(part.uses_options, name) else: - o = getvalue(options, name) + o = getdict(global_uses_options, name) if (o): return o.isset() return 0 -def isused(name, part): - if (part): - o = getvalue(part.options, name) - else: - o = getvalue(options, name) - if (o): - return o.isused() - return 0 +#def isused(name, part): +# global global_options +# if (part): +# o = getdict(part.uses_options, name) +# else: +# o = getdict(global_options, name) +# if (o): +# return o.isused() +# return 0 def usesoption(name): - global curpart - curpart.usesoption(name) + global curpart, global_options, global_uses_options + if (curpart): + curpart.usesoption(name) + return + o = getdict(global_options, name) + if (o == 0): + fatal("Error: can't use undefined option %s" % name) + o.setused() + o1 = getdict(global_uses_options, name) + if (o1): + return + setdict(global_uses_options, name, o) def validdef(name, defval): - o = getvalue(options, name) + global global_options + o = getdict(global_options, name) if (not o): fatal("validdef: %s not here" % name) if ((defval & 1) != 1): @@ -561,7 +788,6 @@ def validdef(name, defval): fatal("Error: must specify comment for option %s" % name) def loadoptions(): - global treetop optionsfile = os.path.join(treetop, 'src', 'config', 'Options.lb') loc.push_file(optionsfile) if (not parse('options', open(optionsfile, 'r').read())): @@ -569,115 +795,111 @@ def loadoptions(): loc.pop_file() def addinit(path): - global initfile + global curimage, curdir if (path[0] == '/'): - initfile = treetop + '/src/' + path + curimage.setinitfile(treetop + '/src/' + path) else: - initfile = curdir + '/' + path + curimage.setinitfile(curdir + '/' + path) print "Adding init file: %s" % path # we do the crt0include as a dictionary, so that if needed we # can trace who added what when. Also it makes the keys # nice and unique. def addcrt0include(path): - global crt0includes - if (debug > 2): - print "ADDCRT0: %s" % path - crt0includes.append(path) + global curimage + curimage.addinitinclude(0, path) def addinitinclude(str, path): - global initincludes, useinitincludes - useinitincludes = 1 - if (debug > 2): - print "ADDCRT0: %s -> %s" % str, path - o = initinclude(dequote(str), path) - setvalue(initincludes, path, o) + global curimage + curimage.addinitinclude(dequote(str), path) def addldscript(path): - global ldscripts + global curimage, curdir if (path[0] == '/'): fullpath = treetop + '/src/' + path else: fullpath = curdir + '/' + path - #fullpath = os.path.join(curdir, path) - #setvalue(ldscripts, fullpath, loc) if (debug): print "fullpath :%s: curdir :%s: path :%s:" % (fullpath, curdir, path) - ldscripts.append(fullpath) + curimage.addldscript(fullpath) def payload(path): - global payloadfile + global curimage adduserdefine("PAYLOAD:=%s"%path) + curimage.addpayload(path) # addrule('payload') # adddep('payload', path) # addaction('payload', 'cp $< $@') -# this is called with an an object name. -# the easiest thing to do is add this object to the current -# component. -# such kludgery. If the name starts with '.' then make the -# dependency be on ./thing.x gag me. -def addobjectdriver(dict, object_name): - suffix = object_name[-2:] - if (suffix == '.o'): - suffix = '.c' - base = object_name[:-2] - if (object_name[0] == '.'): - source = base + suffix - else: - source = os.path.join(curdir, base + suffix) - object = base + '.o' - if (debug): - print "add object %s source %s" % (object_name, source) - setvalue(dict, base, [object, source]) +def addromimage(name): + global romimages, curimage, curpart, target_dir, target_name + print "Configuring ROMIMAGE %s" % name + curimage = romimage(name) + curimage.settargetdir(os.path.join(target_dir, name)) + o = partobj(curimage, target_dir, 0, 'board', target_name) + curimage.setroot(o) + curpart = o + o = getdict(romimages, name) + if (o): + fatal("romimage %s previously defined" % name) + setdict(romimages, name, curimage) + +def addbuildrom(size, roms): + global buildroms + print "Build ROM size %d" % size + b = buildrom(size, roms) + buildroms.append(b) def addinitobject(object_name): - addobjectdriver(initobjectrules, object_name) + global curimage + curimage.addinitobjectrule(object_name) def addobject(object_name): - addobjectdriver(objectrules, object_name) + global curimage + curimage.addobjectrule(object_name) def adddriver(driver_name): - addobjectdriver(driverrules, driver_name) - -def target(targ_name): - global target_dir - global curpart - global root - print "Configuring TARGET %s" % targ_name - target_dir = os.path.join(os.path.dirname(loc.file()), targ_name) - if not os.path.isdir(target_dir): - print "Creating directory %s" % target_dir - os.makedirs(target_dir) - print "Will place Makefile, crt0.S, etc. in %s" % target_dir - root = partobj(target_dir, 0, 'board', targ_name) - curpart = root + global curimage + curimage.adddriverrule(driver_name) + +def target(name): + global target_dir, target_name + print "Configuring TARGET %s" % name + target_name = name + target_dir = os.path.join(os.path.dirname(loc.file()), name) + if not os.path.isdir(target_dir): + print "Creating directory %s" % target_dir + os.makedirs(target_dir) + print "Will place Makefile, crt0.S, etc. in %s" % target_dir + def part(name, path, file): - global curpart,curdir,treetop + global curimage, curpart, curdir, dirstack, pstack dirstack.append(curdir) curdir = os.path.join(treetop, 'src', name, path) - newpart = partobj(curdir, curpart, name, path) + newpart = partobj(curimage, curdir, curpart, name, path) print "Configuring PART %s, path %s" % (name,path) if (debug): - print "PUSH part %s %s" % (name, curpart.dir) + print "PUSH part %s %s" % (name, curdir) pstack.push(curpart) curpart = newpart doconfigfile(curdir, file) def partpop(): - global curpart,curdir + global curpart, curdir, dirstack, pstack print "End PART %s" % curpart.type # Warn if options are used without being set in this part - for i in curpart.options.keys(): + for i in curpart.uses_options.keys(): if (not isset(i, curpart)): - print "WARNING: Option %s using default value %s" % (i, getformated(i, curpart)) + print "WARNING: Option %s using default value %s" % (i, getformated(i, curpart.image.getvalues())) curpart = pstack.pop() + if pstack.empty(): + curpart = 0 curdir = dirstack.pop() # dodir is like part but there is no new part def dodir(path, file): - global curdir, treetop + global curimage, curpart, curdir, dirstack # if the first char is '/', it is relative to treetop, # else relative to curdir # os.path.join screws up if the name starts with '/', sigh. @@ -692,16 +914,61 @@ def dodir(path, file): dirstack.append(curdir) curdir = fullpath file = os.path.join(fullpath, file) - config_file_list.append(file) doconfigfile(fullpath, file) curdir = dirstack.pop() def lookup(name): - global curpart - v = getoption(name, curpart) + global curimage, curpart + if (curpart): + v = getoption(name, curpart) + else: + v = getoption(name, 0) exitiferrors() return v +def addrule(id): + global curimage + curimage.addmakerule(id) + +def adduserdefine(str): + global curimage + curimage.adduserdefine(str) + +def addaction(id, str): + global curimage + curimage.addmakeaction(id, str) + +def adddep(id, str): + global curimage + curimage.addmakedepend(id, str) + +# arch is 'different' ... darn it. +def set_arch(my_arch): + global curimage + curimage.setarch(my_arch) + setoption('ARCH', my_arch) + part('arch', my_arch, 'Config.lb') + +def mainboard(path): + full_path = os.path.join(treetop, 'src/mainboard', path) + setoption('MAINBOARD', full_path) + vendor = re.sub("/.*", "", path) + part_number = re.sub("[^/]/", "", path) + setoption('MAINBOARD_VENDOR', vendor) + setoption('MAINBOARD_PART_NUMBER', part_number) + dodir('/config', 'Config.lb') + part('mainboard', path, 'Config.lb') + +def doconfigfile(path, file): + filename = os.path.join(path, file) + loc.push_file(filename) + if (not parse('cfgfile', open(filename, 'r').read())): + fatal("Error: Could not parse file") + exitiferrors() + +#============================================================================= +# MISC FUNCTIONS +#============================================================================= def ternary(val, yes, no): if (debug): print "ternary %s" % expr @@ -728,13 +995,6 @@ def IsInt( str ): except ValueError: return 0 -def addrule(id): - o = makerule(id) - setvalue(makebaserules, id, o) - -def adduserdefine(str): - userdefines.append(str) - def dequote(str): a = re.sub("^\"", "", str) a = re.sub("\"$", "", a) @@ -746,25 +1006,8 @@ def flatten_name(str): a = re.sub("/", "_", str) return a -def addaction(id, str): - o = getvalue(makebaserules, id) - if (o): - a = dequote(str) - o.addaction(a) - return - fatal("No such rule \"%s\" for addaction" % id); - -def adddep(id, str): - o = getvalue(makebaserules, id) - if (o): - a = dequote(str) - o.adddependency(a) - return - fatal("No such rule \"%s\" for adddependency" % id); - # If the first part of matches treetop, replace that part with "$(TOP)" def topify(path): - global treetop if path[0:len(treetop)] == treetop: path = path[len(treetop):len(path)] if (path[0:1] == "/"): @@ -772,345 +1015,68 @@ def topify(path): path = "$(TOP)/" + path return path -# arch is 'different' ... darn it. -def set_arch(my_arch): - global arch - global curdir - arch = my_arch - setoption('ARCH', my_arch) - #part('arch', my_arch, 'config/make.base.lb') - part('arch', my_arch, 'Config.lb') - +%% +parser Config: + ignore: r'\s+' + ignore: "#.*?\r?\n" -def mainboard(path): - global mainboard_dir, treetop - mainboard_dir = path - full_mainboard_dir = os.path.join(treetop, 'src/mainboard', path) - setoption('MAINBOARD', full_mainboard_dir) - vendor = re.sub("/.*", "", path) - mainboard_part_number = re.sub("[^/]/", "", path) - setoption('MAINBOARD_VENDOR', vendor) - setoption('MAINBOARD_PART_NUMBER', mainboard_part_number) - dodir('/config', 'Config.lb') - part('mainboard', path, 'Config.lb') - -#============================================================================= -# FILE OUTPUT -#============================================================================= -def writemakefileheader(file, fname): - file.write("# File: %s\n" % fname) - file.write("# This file was generated by '%s %s %s'\n\n" - % (sys.argv[0], sys.argv[1], sys.argv[2])) - - -def writemakefilesettings(path): - global treetop, arch, mainboard_dir, target_dir, root - global options_by_order, options - # Write Makefile.settings to seperate the settings - # from the actual makefile creation - # In practice you need to rerun NLBConfig.py to change - # these but in theory you shouldn't need to. - - filename = os.path.join(path, "Makefile.settings") - print "Creating", filename - file = open(filename, 'w+') - writemakefileheader(file, filename) - file.write("TOP:=%s\n" % (treetop)) - #file.write("ARCH:=%s\n" % (arch)) - #file.write("MAINBOARD:=%s\n" % (mainboard_dir)) - file.write("TARGET_DIR:=%s\n" % (target_dir)) - for i in options_by_order: - if (isexported(i, 0)): - file.write("export %s:=%s\n" % (i, getformated(i, 0))) - file.write("export VARIABLES := ") - for i in options.keys(): - if (isexported(i, 0)): - file.write("%s " % i) - file.write("\n") -# file.write("CPUFLAGS := ") -# for i in options.keys(): -# o = options[i] -# file.write("-D%s=%s " % (i, o.getvalue())) -# file.write("\n") - file.close() - - -# write the makefile -# let's try the Makefile -# first, dump all the -D stuff - -def writemakefile(path): - global root, useinitincludes - makefilepath = os.path.join(path, "Makefile") - print "Creating", makefilepath - file = open(makefilepath, 'w+') - writemakefileheader(file, makefilepath) - - # file.write("include Makefile.settings\n") - # file.write("include cpuflags\n") - # Putting "include cpuflags" in the Makefile has the problem that the - # cpuflags file would be generated _after_ we want to include it. - # Instead, let make do the work of computing CPUFLAGS: - file.write("""\ -# Get the value of TOP, VARIABLES, and several other variables. -include Makefile.settings - -# Function to create an item like -Di586 or -DMAX_CPUS='1' or -Ui686 -D_item = $(if $(subst undefined,,$(origin $1)),-D$1$(if $($1),='$($1)',),-U$1) - -# Compute the value of CPUFLAGS here during make's first pass. -CPUFLAGS := $(foreach _var_,$(VARIABLES),$(call D_item,$(_var_))) -""") - - for i in userdefines: - file.write("%s\n" %i) - file.write("\n") - - # main rule - file.write("all: linuxbios.rom") - # print out all the object dependencies - file.write("\n# object dependencies (objectrules:)\n") - file.write("INIT-OBJECTS :=\n") - file.write("OBJECTS :=\n") - file.write("DRIVER :=\n") - file.write("\nSOURCES :=\n") - for irule in initobjectrules.keys(): - init = initobjectrules[irule] - i_name = init[0] - i_source = init[1] - file.write("INIT-OBJECTS += %s\n" % (i_name)) - file.write("SOURCES += %s\n" % (i_source)) - - for objrule in objectrules.keys(): - obj = objectrules[objrule] - obj_name = obj[0] - obj_source = obj[1] - file.write("OBJECTS-1 += %s\n" % (obj_name)) - file.write("SOURCES += %s\n" % (obj_source)) - - for driverrule in driverrules.keys(): - driver = driverrules[driverrule] - obj_name = driver[0] - obj_source = driver[1] - file.write("DRIVER += %s\n" % (obj_name)) - file.write("SOURCES += %s\n" % (obj_source)) - - # Print out all ldscript.ld dependencies. - file.write("\n# ldscript.ld dependencies:\n") - file.write("LDSUBSCRIPTS-1 := \n" ) - for script in ldscripts: - file.write("LDSUBSCRIPTS-1 += %s\n" % topify(script)) - - # Print out the dependencies for crt0_includes.h - file.write("\n# Dependencies for crt0_includes.h\n") - file.write("CRT0_INCLUDES:=\n") - if (useinitincludes): - for inc in initincludes.keys(): - if (local_path.match(inc)): - file.write("CRT0_INCLUDES += %s\n" % inc) - else: - file.write("CRT0_INCLUDES += $(TOP)/src/%s\n" % inc) - else: - for i in crt0includes: - if (local_path.match(i)): - file.write("CRT0_INCLUDES += %s\n" % i) - else: - file.write("CRT0_INCLUDES += $(TOP)/src/%s\n" % i) - - - # Print out the user defines. - file.write("\n# userdefines:\n") - #for udef in userdefines: - #file.write("%s\n" % udef) - - # Print out the base rules. - # Need to have a rule that counts on 'all'. - file.write("\n# mainrulelist:") - #file.write("\nmainrule: %s\n" % mainrulelist) - - # Print out any user rules. - file.write("\n# From makerule or docipl commands:\n") - # Old way (hash order): for target in makebaserules.keys(): - # New way (config file order): - #for target in makerule_targets: - #makebaserules[target].write(file) - - file.write("\n# objectrules:\n") - for objrule in objectrules.keys(): - obj = objectrules[objrule] - source = topify(obj[1]) - file.write("%s: %s\n" % (obj[0], source)) - file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n") - #file.write("%s\n" % objrule[2]) - - for driverrule in driverrules.keys(): - driver = driverrules[driverrule] - source = topify(driver[1]) - file.write("%s: %s\n" % (driver[0], source)) - file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n") - #file.write("%s\n" % objrule[2]) - - # Print out the rules that will make cause the files - # generated by NLBConfig.py to be remade if any dependencies change. - - file.write("\n# Remember the automatically generated files\n") - file.write("GENERATED:=\n") - for genfile in [ 'Makefile', - 'Makefile.settings', - 'nsuperio.c', - 'chip.c', - 'LinuxBIOSDoc.config' ]: - file.write("GENERATED += %s\n" % genfile) - if (useinitincludes): - file.write("GENERATED += crt0.S\n") - else: - file.write("GENERATED += crt0_includes.h\n") - - file.write("\n# Remake Makefile (and the other files generated by\n") - file.write("# NLBConfig.py) if any config dependencies change.\n") - - for cfile in config_file_list: - file.write("$(GENERATED): %s\n" % topify(cfile)) - - for depfile in [ '%s' % top_config_file, # This a duplicate, remove? - '$(TOP)/util/config/NLBConfig.py', - '$(TOP)/src/arch/$(ARCH)/config/make.base' ]: - file.write("$(GENERATED): %s\n" % depfile) - - file.write("$(GENERATED):\n") - file.write("\tpython $(TOP)/util/config/NLBConfig.py %s $(TOP)\n" - % top_config_file) - - keys = root.options.keys() - keys.sort() - file.write("\necho:\n") - for key in keys: - file.write("\t@echo %s='$(%s)'\n"% (key,key)) - - - for i in makebaserules.keys(): - m = makebaserules[i] - file.write("%s: " %i) - for i in m.dependency: - file.write("%s " % i) - file.write("\n") - for i in m.actions: - file.write("\t%s\n" % i) - file.close() - -# Write out crt0_includes.h (top-level assembly language) include file. -def writecrt0_includes(path): - crt0filepath = os.path.join(path, "crt0_includes.h") - print "Creating", crt0filepath - file = open(crt0filepath, 'w+') - for i in crt0includes: - file.write("#include <%s>\n" % i) - - file.close() - -def writeinitincludes(path): - global initfile, include_pattern, crt0_includes - crt0filepath = os.path.join(path, "crt0.S") - print "Creating", crt0filepath - infile = open(initfile, 'r') - outfile = open(crt0filepath, 'w+') - - line = infile.readline() - while (line): - p = include_pattern.match(line) - if (p): - for i in initincludes.keys(): - inc = initincludes[i] - if (inc.getstring() == p.group(1)): - outfile.write("#include \"%s\"\n" % inc.getpath()) - else: - outfile.write(line); - line = infile.readline() - - infile.close() - outfile.close() - -def writeldoptions(path): - global options - # Write Makefile.settings to seperate the settings - # from the actual makefile creation - # In practice you need to rerun NLBConfig.py to change - # these but in theory you shouldn't need to. - - filename = os.path.join(path, "ldoptions") - print "Creating", filename - file = open(filename, 'w+') - for i in options.keys(): - if (isexported(i, 0) and IsInt(getoption(i, 0))): - file.write("%s = %s;\n" % (i, getformated(i, 0))) - file.close() - -# Add any run-time checks to verify that parsing the configuration -# was successful -def verifyparse(): - global useinitincludes, initfile - if (useinitincludes and initfile == ''): - fatal("An init file must be specified") - -%% -parser Config: - ignore: r'\s+' - ignore: "#.*?\r?\n" - - # less general tokens should come first, otherwise they get matched - # by the re's - token ACTION: 'action' - token ADDACTION: 'addaction' - token ALWAYS: 'always' - token ARCH: 'arch' - token COMMENT: 'comment' - token CPU: 'cpu' - token DEFAULT: 'default' - token DEFINE: 'define' - token DEPENDS: 'depends' - token DIR: 'dir' - token DRIVER: 'driver' - token ELSE: 'else' - token END: '$|end' - token EQ: '=' - token EXPORT: 'export' - token FORMAT: 'format' - token IF: 'if' - token INIT: 'init' - token INITOBJECT: 'initobject' - token INITINCLUDE: 'initinclude' - token LDSCRIPT: 'ldscript' - token LOADOPTIONS: 'loadoptions' - token MAINBOARD: 'mainboard' - token MAINBOARDINIT: 'mainboardinit' - token MAKEDEFINE: 'makedefine' - token MAKERULE: 'makerule' - token NEVER: 'never' - token NONE: 'none' - token NORTHBRIDGE: 'northbridge' - token OBJECT: 'object' - token OPTION: 'option' - token PAYLOAD: 'payload' - token PMC: 'pmc' - token PRINT: 'print' - token REGISTER: 'register' - token SOUTHBRIDGE: 'southbridge' - token SUPERIO: 'superio' - token TARGET: 'target' - token USED: 'used' - token USES: 'uses' - token NUM: r'[0-9]+' - token XNUM: r'0x[0-9a-fA-F]+' - # Why is path separate? Because paths to resources have to at least - # have a slash, we thinks - token PATH: r'[a-zA-Z0-9_.][a-zA-Z0-9/_.]+[a-zA-Z0-9_.]+' - # Dir's on the other hand are abitrary - # this may all be stupid. - token DIRPATH: r'[-a-zA-Z0-9_$()./]+' - token ID: r'[a-zA-Z_.]+[a-zA-Z0-9_.]*' - token DELEXPR: r'{([^}]+|\\.)*}' - token STR: r'"([^\\"]+|\\.)*"' - token RAWTEXT: r'.*' + # less general tokens should come first, otherwise they get matched + # by the re's + token ACTION: 'action' + token ADDACTION: 'addaction' + token ALWAYS: 'always' + token ARCH: 'arch' + token BUILDROM: 'buildrom' + token COMMENT: 'comment' + token CPU: 'cpu' + token DEFAULT: 'default' + token DEFINE: 'define' + token DEPENDS: 'depends' + token DIR: 'dir' + token DRIVER: 'driver' + token ELSE: 'else' + token END: 'end' + token EOF: '$' + token EQ: '=' + token EXPORT: 'export' + token FORMAT: 'format' + token IF: 'if' + token INIT: 'init' + token INITOBJECT: 'initobject' + token INITINCLUDE: 'initinclude' + token LDSCRIPT: 'ldscript' + token LOADOPTIONS: 'loadoptions' + token MAINBOARD: 'mainboard' + token MAINBOARDINIT: 'mainboardinit' + token MAKEDEFINE: 'makedefine' + token MAKERULE: 'makerule' + token NEVER: 'never' + token NONE: 'none' + token NORTHBRIDGE: 'northbridge' + token OBJECT: 'object' + token OPTION: 'option' + token PAYLOAD: 'payload' + token PMC: 'pmc' + token PRINT: 'print' + token REGISTER: 'register' + token ROMIMAGE: 'romimage' + token SOUTHBRIDGE: 'southbridge' + token SUPERIO: 'superio' + token TARGET: 'target' + token USED: 'used' + token USES: 'uses' + token NUM: r'[0-9]+' + token XNUM: r'0x[0-9a-fA-F]+' + # Why is path separate? Because paths to resources have to at least + # have a slash, we thinks + token PATH: r'[a-zA-Z0-9_.][a-zA-Z0-9/_.]+[a-zA-Z0-9_.]+' + # Dir's on the other hand are abitrary + # this may all be stupid. + token DIRPATH: r'[-a-zA-Z0-9_$()./]+' + token ID: r'[a-zA-Z_.]+[a-zA-Z0-9_.]*' + token DELEXPR: r'{([^}]+|\\.)*}' + token STR: r'"([^\\"]+|\\.)*"' + token RAWTEXT: r'.*' rule expr: logical {{ l = logical }} ( "&&" logical {{ l = l and logical }} @@ -1138,11 +1104,8 @@ parser Config: rule unop: "!" expr {{ return not(expr) }} - rule partend<>: (stmt<>)* END {{ partpop()}} + rule partend<>: (stmt<>)* END {{ if (C): partpop()}} - rule mainboard: MAINBOARD PATH {{ mainboard(PATH) }} - partend<<1>> - rule northbridge<>: NORTHBRIDGE PATH {{ if (C): part('northbridge', PATH, 'Config.lb') }} partend<> @@ -1188,7 +1151,9 @@ parser Config: # needs to be C and ID, but nested if's are, we hope, not going to # happen. IF so, possibly ID && C could be used. rule iif<>: IF ID {{ c = lookup(ID) }} - (stmt<>)* [ ELSE (stmt<>)* ] END + (stmt<>)* + [ ELSE (stmt<>)* ] + END rule depsacts<>: ( DEPENDS STR {{ if (C): adddep(ID, STR) }} @@ -1209,35 +1174,47 @@ parser Config: rule register<>: REGISTER STR {{ if (C): curpart.addregister(STR) }} + rule prtval: expr {{ return str(expr) }} + | STR {{ return STR }} + + rule prtlist: prtval {{ el = "%(" + prtval }} + ( "," prtval {{ el = el + "," + prtval }} + )* {{ return el + ")" }} + + rule prtstmt<>: PRINT STR {{ val = STR }} + [ "," prtlist {{ val = val + prtlist }} + ] {{ if (C): print eval(val) }} + # to make if work without 2 passses, we use an old hack from SIMD, the # context bit. If the bit is 1, then ops get done, otherwise # ops don't get done. From the top level, context is always # 1. In an if, context depends on eval of the if condition - rule stmt<>: cpu<> {{ return cpu}} - | pmc<> {{ return pmc}} + rule stmt<>: addaction<> {{ return addaction }} | arch<> {{ return arch}} - | northbridge<> {{ return northbridge }} - | southbridge<> {{ return southbridge }} - | superio<> {{ return superio }} - | initobject<> {{ return initobject }} - | object<> {{ return object }} + | cpu<> {{ return cpu}} + | dir<> {{ return dir}} | driver<> {{ return driver }} - | mainboardinit<> {{ return mainboardinit }} - | initinclude<> {{ return initinclude }} - | makerule<> {{ return makerule }} - | makedefine<> {{ return makedefine }} - | addaction<> {{ return addaction }} - | init<> {{ return init }} - | register<> {{ return register}} | iif<> {{ return iif }} - | dir<> {{ return dir}} + | init<> {{ return init }} + | initinclude<> {{ return initinclude }} + | initobject<> {{ return initobject }} | ldscript<> {{ return ldscript}} + | mainboardinit<> {{ return mainboardinit }} + | makedefine<> {{ return makedefine }} + | makerule<> {{ return makerule }} + | northbridge<> {{ return northbridge }} + | object<> {{ return object }} | payload<> {{ return payload}} + | pmc<> {{ return pmc}} | prtstmt<> {{ return prtstmt}} + | register<> {{ return register}} + | southbridge<> {{ return southbridge }} + | superio<> {{ return superio }} # ENTRY for parsing Config.lb file - rule cfgfile: (uses<<1>>)* (stmt<<1>>)* - {{ return 1 }} + rule cfgfile: (uses<<1>>)* + (stmt<<1>>)* + EOF {{ return 1 }} rule usesid<>: ID {{ if (C): usesoption(ID) }} @@ -1247,36 +1224,42 @@ parser Config: | expr {{ return expr }} | DELEXPR {{ return DELEXPR }} - rule option<>: OPTION ID EQ value {{ if (C): setoptionstmt(ID, value) }} + rule option<>: OPTION ID EQ value {{ if (C): setoption(ID, value) }} rule opif<>: IF ID {{ c = lookup(ID) }} (opstmt<>)* - [ ELSE (opstmt<>)* ] END + [ ELSE (opstmt<>)* ] + END rule opstmt<>: option<> | opif<> | prtstmt<> - rule prtval: expr {{ return str(expr) }} - | STR {{ return STR }} - rule prtlist: prtval {{ el = "%(" + prtval }} - ( "," prtval {{ el = el + "," + prtval }} - )* {{ return el + ")" }} + rule romimage: ROMIMAGE STR {{ addromimage(dequote(STR)) }} + (option<<1>>)* + MAINBOARD PATH {{ mainboard(PATH) }} + END {{ partpop(); print "End ROMIMAGE" }} - rule prtstmt<>: PRINT STR {{ val = STR }} - [ "," prtlist {{ val = val + prtlist }} - ] {{ if (C): print eval(val) }} + rule roms: STR {{ s = '(' + STR }} + ( STR {{ s = s + "," + STR }} + )* {{ return eval(s + ')') }} - # ENTRY for parsing a delayed value - rule delexpr: "{" expr "}" {{ return expr }} + rule buildrom: BUILDROM expr roms {{ addbuildrom(expr, roms) }} + + rule romstmts: (romimage)* + buildrom # ENTRY for parsing root part rule board: LOADOPTIONS {{ loadoptions() }} TARGET DIRPATH {{ target(DIRPATH) }} (uses<<1>>)* (opstmt<<1>>)* - mainboard {{ return 1 }} + (romstmts)* + EOF {{ return 1 }} + + # ENTRY for parsing a delayed value + rule delexpr: "{" expr "}" EOF {{ return expr }} rule defstmts<>: {{ d = 0 }} ( DEFAULT @@ -1296,9 +1279,274 @@ parser Config: defstmts<> END {{ validdef(ID, defstmts) }} # ENTRY for parsing Options.lb file - rule options: (define)* END {{ return 1 }} + rule options: (define)* EOF {{ return 1 }} %% +#============================================================================= +# FILE OUTPUT +#============================================================================= +def writemakefileheader(file, fname): + file.write("# File: %s\n" % fname) + file.write("# This file was generated by '%s %s %s'\n\n" + % (sys.argv[0], sys.argv[1], sys.argv[2])) + +def writemakefilesettings(path): + global treetop, target_dir + # Write Makefile.settings to seperate the settings + # from the actual makefile creation + # In practice you need to rerun NLBConfig.py to change + # these but in theory you shouldn't need to. + + filename = os.path.join(path, "Makefile.settings") + print "Creating", filename + file = open(filename, 'w+') + writemakefileheader(file, filename) + file.write("TOP:=%s\n" % (treetop)) + file.write("TARGET_DIR:=%s\n" % target_dir) +# for i in global_options_by_order: +# if (isexported(i, 0)): +# file.write("export %s:=%s\n" % (i, getformated(i, 0))) +# file.write("export VARIABLES := ") +# for i in global_options.keys(): +# if (isexported(i, 0)): +# file.write("%s " % i) + file.write("\n") + file.close() + +def writeimagesettings(image): + global treetop + global global_options_by_order + # Write Makefile.settings to seperate the settings + # from the actual makefile creation + # In practice you need to rerun NLBConfig.py to change + # these but in theory you shouldn't need to. + + filename = os.path.join(image.gettargetdir(), "Makefile.settings") + print "Creating", filename + file = open(filename, 'w+') + writemakefileheader(file, filename) + file.write("TOP:=%s\n" % (treetop)) + file.write("TARGET_DIR:=%s\n" % (image.gettargetdir())) + for i in global_options_by_order: + if (isexported(i)): + file.write("export %s:=%s\n" % (i, getformated(i, image.getvalues()))) + file.write("export VARIABLES := ") + for i in global_options_by_order: + if (isexported(i)): + file.write("%s " % i) + file.write("\n") + file.close() + +# write the romimage makefile +# let's try the Makefile +# first, dump all the -D stuff + +def writeimagemakefile(image): + makefilepath = os.path.join(image.gettargetdir(), "Makefile") + print "Creating", makefilepath + file = open(makefilepath, 'w+') + writemakefileheader(file, makefilepath) + + #file.write("include cpuflags\n") + # Putting "include cpuflags" in the Makefile has the problem that the + # cpuflags file would be generated _after_ we want to include it. + # Instead, let make do the work of computing CPUFLAGS: + file.write("# Get the value of TOP, VARIABLES, and several other variables.\n") + file.write("include Makefile.settings\n\n") + file.write("# Function to create an item like -Di586 or -DMAX_CPUS='1' or -Ui686\n") + file.write("D_item = $(if $(subst undefined,,$(origin $1)),-D$1$(if $($1),='$($1)',),-U$1)\n\n") + file.write("# Compute the value of CPUFLAGS here during make's first pass.\n") + file.write("CPUFLAGS := $(foreach _var_,$(VARIABLES),$(call D_item,$(_var_)))\n\n") + + for i in image.getuserdefines(): + file.write("%s\n" %i) + file.write("\n") + + # main rule + file.write("all: linuxbios.rom") + # print out all the object dependencies + file.write("\n# object dependencies (objectrules:)\n") + file.write("INIT-OBJECTS :=\n") + file.write("OBJECTS :=\n") + file.write("DRIVER :=\n") + file.write("\nSOURCES :=\n") + for irule in image.getinitobjectrules().keys(): + init = image.getinitobjectrule(irule) + i_name = init[0] + i_source = init[1] + file.write("INIT-OBJECTS += %s\n" % (i_name)) + file.write("SOURCES += %s\n" % (i_source)) + + for objrule in image.getobjectrules().keys(): + obj = image.getobjectrule(objrule) + obj_name = obj[0] + obj_source = obj[1] + file.write("OBJECTS-1 += %s\n" % (obj_name)) + file.write("SOURCES += %s\n" % (obj_source)) + + for driverrule in image.getdriverrules().keys(): + driver = image.getdriverrule(driverrule) + obj_name = driver[0] + obj_source = driver[1] + file.write("DRIVER += %s\n" % (obj_name)) + file.write("SOURCES += %s\n" % (obj_source)) + + # Print out all ldscript.ld dependencies. + file.write("\n# ldscript.ld dependencies:\n") + file.write("LDSUBSCRIPTS-1 := \n" ) + for script in image.getldscripts(): + file.write("LDSUBSCRIPTS-1 += %s\n" % topify(script)) + + # Print out the dependencies for crt0_includes.h + file.write("\n# Dependencies for crt0_includes.h\n") + file.write("CRT0_INCLUDES:=\n") + for inc in image.getinitincludes().keys(): + if (local_path.match(inc)): + file.write("CRT0_INCLUDES += %s\n" % inc) + else: + file.write("CRT0_INCLUDES += $(TOP)/src/%s\n" % inc) + + # Print out the user defines. + file.write("\n# userdefines:\n") + #for udef in image.userdefines: + #file.write("%s\n" % udef) + + # Print out the base rules. + # Need to have a rule that counts on 'all'. + file.write("\n# mainrulelist:") + #file.write("\nmainrule: %s\n" % image.mainrulelist) + + # Print out any user rules. + file.write("\n# From makerule or docipl commands:\n") + # Old way (hash order): for target in makebaserules.keys(): + # New way (config file order): + #for target in image.makerule_targets: + #image.makebaserules[target].write(file) + + file.write("\n# objectrules:\n") + for objrule in image.getobjectrules().keys(): + obj = image.getobjectrule(objrule) + source = topify(obj[1]) + file.write("%s: %s\n" % (obj[0], source)) + file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n") + #file.write("%s\n" % objrule[2]) + + for driverrule in image.getdriverrules().keys(): + driver = image.getdriverrule(driverrule) + source = topify(driver[1]) + file.write("%s: %s\n" % (driver[0], source)) + file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n") + #file.write("%s\n" % objrule[2]) + + # Print out the rules that will make cause the files + # generated by NLBConfig.py to be remade if any dependencies change. + + file.write("\n# Remember the automatically generated files\n") + file.write("GENERATED:=\n") + for genfile in [ 'Makefile', + 'nsuperio.c', + 'chip.c', + 'LinuxBIOSDoc.config' ]: + file.write("GENERATED += %s\n" % genfile) + file.write("GENERATED += %s\n" % image.getincludefilename()) + + #file.write("\n# Remake Makefile (and the other files generated by\n") + #file.write("# NLBConfig.py) if any config dependencies change.\n") + + #for cfile in image.config_file_list: + # file.write("$(GENERATED): %s\n" % topify(cfile)) + + #for depfile in [ '%s' % top_config_file, # This a duplicate, remove? + # '$(TOP)/util/config/NLBConfig.py', + # '$(TOP)/src/arch/$(ARCH)/config/make.base' ]: + # file.write("$(GENERATED): %s\n" % depfile) + + #file.write("$(GENERATED):\n") + #file.write("\tpython $(TOP)/util/config/NLBConfig.py %s $(TOP)\n" + # % top_config_file) + + keys = image.getroot().uses_options.keys() + keys.sort() + file.write("\necho:\n") + for key in keys: + file.write("\t@echo %s='$(%s)'\n"% (key,key)) + + for i in image.getmakerules().keys(): + m = image.getmakerule(i) + file.write("%s: " %i) + for i in m.dependency: + file.write("%s " % i) + file.write("\n") + for i in m.actions: + file.write("\t%s\n" % i) + file.close() + +# +def writemakefile(path): + makefilepath = os.path.join(path, "Makefile") + print "Creating", makefilepath + file = open(makefilepath, 'w+') + writemakefileheader(file, makefilepath) + + # main rule + file.write("all: ") + for i in romimages.keys(): + file.write("%s-rom " % i) + file.write("\n\n") + for i in romimages.keys(): + o = getdict(romimages, i) + file.write("%s-rom:\n" % o.getname()) + file.write("\tif (cd %s; \\\n" % o.getname()) + file.write("\t\tmake linuxbios.rom)\\\n"); + file.write("\tthen true; else exit 1; fi;\n\n") + file.close() + +def writeinitincludes(image): + global include_pattern + filepath = os.path.join(image.gettargetdir(), image.getincludefilename()) + print "Creating", filepath + outfile = open(filepath, 'w+') + if (image.newformat()): + infile = open(image.getinitfile(), 'r') + + line = infile.readline() + while (line): + p = include_pattern.match(line) + if (p): + for i in image.getinitincludes().keys(): + inc = image.getinitinclude(i) + if (inc.getstring() == p.group(1)): + outfile.write("#include \"%s\"\n" % inc.getpath()) + else: + outfile.write(line); + line = infile.readline() + + infile.close() + else: + for i in image.getinitincludes().keys(): + outfile.write("#include <%s>\n" % i) + outfile.close() + +def writeldoptions(image): + # Write Makefile.settings to seperate the settings + # from the actual makefile creation + # In practice you need to rerun NLBConfig.py to change + # these but in theory you shouldn't need to. + + filename = os.path.join(image.gettargetdir(), "ldoptions") + print "Creating", filename + file = open(filename, 'w+') + for i in global_options.keys(): + if (isexported(i) and IsInt(getoption(i, 0))): + file.write("%s = %s;\n" % (i, getformated(i, image.getvalues()))) + file.close() + +# Add any run-time checks to verify that parsing the configuration +# was successful +def verifyparse(image): + if (image.newformat() and image.getinitfile() == ''): + fatal("An init file must be specified") + def dumptree(part, lvl): if (debug): print "DUMPTREE ME is" @@ -1339,15 +1587,10 @@ def gencode(part, file): gencode(part.children, file) if (debug): print "DONE GENCODE" - - -def doconfigfile(path, file): - filename = os.path.join(path, file) - loc.push_file(filename) - if (not parse('cfgfile', open(filename, 'r').read())): - fatal("Error: Could not parse file") - exitiferrors() +#============================================================================= +# MAIN PROGRAM +#============================================================================= if __name__=='__main__': from sys import argv if (len(argv) < 3): @@ -1363,42 +1606,55 @@ if __name__=='__main__': if (not parse('board', open(argv[1], 'r').read())): fatal("Error: Could not parse file") - verifyparse() + for r in romimages.keys(): + verifyparse(getdict(romimages, r)) - if (debug): - print "DEVICE TREE:" - dumptree(root, 0) + # no longer need to check if an options has been used + alloptions = 1 - filename = os.path.join(target_dir, "chips.c") - print "Creating", filename - file = open(filename, 'w+') - # gen all the forward references - - i = 0 - file.write("struct chip ") - while (i <= partinstance): - file.write("cdev%d "% i) - i = i + 1 - file.write(";\n") - gencode(root, file) - file.close() + for r in romimages.keys(): + image = getdict(romimages, r) - # crt0 includes - if (debug): - for i in crt0includes: - print "crt0include file %s" % (i) - for i in driverrules.keys(): - print "driver file %s" % (i) - for i in ldscripts: - print "ldscript file %s" % (i) - for i in makebaserules.keys(): - m = makebaserules[i] - print " makerule %s dep %s act %s" % (i, m.dependency, m.actions) + if (debug): + print "DEVICE TREE:" + dumptree(image.getroot(), 0) + + img_dir = image.gettargetdir() + if not os.path.isdir(img_dir): + print "Creating directory %s" % img_dir + os.makedirs(img_dir) + filename = os.path.join(img_dir, "chips.c") + print "Creating", filename + file = open(filename, 'w+') + # gen all the forward references + + i = 0 + file.write("struct chip ") + while (i <= image.getpartinstance()): + file.write("cdev%d "% i) + i = i + 1 + file.write(";\n") + gencode(image.getroot(), file) + file.close() + + # crt0 includes + if (debug): + for i in image.getinitincludes().keys(): + print "crt0include file %s" % (i) + for i in image.getdriverrules().keys(): + print "driver file %s" % (i) + for i in image.getldscripts(): + print "ldscript file %s" % (i) + for i in image.getmakerules().keys(): + m = image.getmakerule(i) + print " makerule %s dep %s act %s" % (i, m.dependency, m.actions) + + writeimagesettings(image) + writeinitincludes(image) + writeimagemakefile(image) + writeldoptions(image) writemakefilesettings(target_dir) - if (useinitincludes): - writeinitincludes(target_dir) - else: - writecrt0_includes(target_dir) writemakefile(target_dir) - writeldoptions(target_dir) + + sys.exit(0) -- cgit v1.2.3