diff options
author | Ronald G. Minnich <rminnich@gmail.com> | 2003-06-14 15:07:02 +0000 |
---|---|---|
committer | Ronald G. Minnich <rminnich@gmail.com> | 2003-06-14 15:07:02 +0000 |
commit | d3e377a520d6ad5997f2ef7c8fc1b823d6d0e7f2 (patch) | |
tree | cb5ec5325af2c2f368b9b4e7ef4e4a32467b352a /util/newconfig/config.g | |
parent | f7092040fd4aba081aad75116c2b9594149d5c66 (diff) |
new config tool
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@878 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
Diffstat (limited to 'util/newconfig/config.g')
-rw-r--r-- | util/newconfig/config.g | 912 |
1 files changed, 912 insertions, 0 deletions
diff --git a/util/newconfig/config.g b/util/newconfig/config.g new file mode 100644 index 0000000000..4222f57630 --- /dev/null +++ b/util/newconfig/config.g @@ -0,0 +1,912 @@ +import sys +import os +import re +import string + +debug = 3 + +arch = '' +makebase = '' +ldscriptbase = '' +payloadfile = '' + +makeoptions = {} +makeexpressions = [] + +# 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 = {} +# make these a hash so they will be unique. +driverrules = {} +ldscripts = [] +userdefines = [] +curpart = 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 = [] +partinstance = 0 +curdir = '' +dirstack = [] +config_file_list = [] + +local_path = re.compile(r'^\.') + +# ----------------------------------------------------------------------------- +# Error Handling +# ----------------------------------------------------------------------------- + +class location: + class place: + def __init__(self, file, line, command): + self.file = file + self.line = line + self.command = command + def next_line(self, command): + self.line = self.line + 1 + self.command = command + def at(self): + return "%s:%d" % (self.file, self.line) + + def __init__ (self): + self.stack = [] + + def file(self): + return self.stack[-1].file + def line(self): + return self.stack[-1].line + def command(self): + return self.stack[-1].command + + def push_file(self, file): + self.stack.append(self.place(file, 0, "")) + def pop_file(self): + self.stack.pop() + def next_line(self, command): + self.stack[-1].next_line(command) + def at(self): + return self.stack[-1].at() +loc = location() + +class makerule: + def __init__ (self, target): + self.target = target + self.dependency = [] + self.actions = [] + + def addaction(self, action): + self.actions.append(action) + + def adddependency(self, dependency): + self.dependency.append(dependency) + + def gtarget(self): + return self.target + + def gdependency(self): + return self.dependency + + def gaction(self): + return self.actions + +class option: + def __init__ (self, name): + self.name = name + self.loc = 0 + self.value = 0 + self.set = 0 + self.default = 0 + + def setvalue(self, value, loc): + if (self.set): + print "Option %s: \n" % self.name + print "Attempt to set %s at %s\n" % (value, loc.at()) + print "Already set to %s at %s\n" % \ + (self.value, self.loc.at()) + sys.exit(1) + self.set = 1 + self.value = value + self.loc = loc + + + def getvalue(self): + self.set = 1 + return self.value + + def setdefault(self, value, loc): + if (self.default): + print "%s: " % self.name + print "Attempt to default %s at %s\n" % (value, loc) + print "Already defaulted to %s at %s\n" % \ + (self.value, self.loc.at()) + print "Warning only\n" + if (self.set): + print "%s: " % self.name + print "Attempt to default %s at %s\n" % (value, loc) + print "Already set to %s at %s\n" % \ + (self.value, self.loc.at()) + print "Warning only\n" + return + self.default = 1 + self.value = value + self.loc = loc + def where(self): + return self.loc + + +class partobj: + def __init__ (self, dir, parent, type): + global partinstance + print "partobj dir %s parent %s type %s" %(dir,parent,type) + self.children = [] + self.initcode = [] + self.registercode = [] + self.siblings = 0 + self.type = type + self.objects = [] + self.dir = dir + self.irq = 0 + self.instance = partinstance + 1 + partinstance = partinstance + 1 + self.devfn = 0 + self.private = 0 + if (parent): + print "add to parent" + self.parent = parent + parent.children.append(self) + else: + self.parent = self + + def dumpme(self, lvl): + print "%d: type %s" % (lvl, self.type) + print "%d: dir %s" % (lvl,self.dir) + print "%d: parent %s" % (lvl,self.parent.type) + print "%d: parent dir %s" % (lvl,self.parent.dir) + print "%d: initcode " % lvl + for i in self.initcode: + print " %s\n" % i + print "%d: registercode " % lvl + for i in self.registercode: + print " %s\n" % i + + def gencode(self): + print "struct cdev dev%d = {" % self.instance + print "/* %s %s */" % (self.type, self.dir) + print " .devfn = %d" % self.devfn + if (self.siblings): + print " .next = &dev%d" % self.sibling.instance + if (self.children): + print " .children = &dev%d" % \ + self.children[0].instance + if (self.private): + print " .private = private%d" % self.instance + print "};" + + + def irq(self, irq): + self.irq = irq + + def addinit(self, code): + self.initcode.append(code) + + def addregister(self, code): + self.registercode.append(code) + + +class partsstack: + def __init__ (self): + self.stack = [] + + def push(self, part): + self.stack.append(part) + + def pop(self): + return self.stack.pop() + + def tos(self): + return self.stack[-1] +pstack = partsstack() + +def fatal(string): + global loc + size = len(loc.stack) + i = 0 + while(i < size -1): + print loc.stack[i].at() + i = i + 1 + print "%s: %s"% (loc.at(), string) + sys.exit(1) + +def warning(string): + global loc + 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) + + +# ----------------------------------------------------------------------------- +# statements +# ----------------------------------------------------------------------------- + +def getvalue(dict, name): + if name not in dict.keys(): print 'Undefined:', name + v = dict.get(name, 0) + if (debug > 1): + print "getvalue %s returning %s\n" % (name, v) + return v + +def setvalue(dict, name, value): + print "name %s value %s" % (name, value) + if name in dict.keys(): print "Warning, %s previously defined" % name + if (debug > 1): + print "setvalue sets %s to %s\n" % (name, value) + dict[name] = value + +# options. +# to create an option, it has to no exist. +# When an option value is fetched, the fact that it was used is +# remembered. +# Legal things to do: +# set a default value, then set a real value before the option is used. +# set a value, try to set a default, default silently fails. +# Illegal: +# use the value, then try to set the value + +def getoption(name): + print "getoption %s" % name + o = getvalue(options, name) + if (o == 0): + fatal( "Error. Option %s Undefined. Fix me.\n" % name) + if (debug > 2): + print "returns %s" % o + print "%s" % o.where() + return o.getvalue() + +# stupid code, refactor later. +def setoption(name, value): + o = getvalue(options, name) + if (o): + o.setvalue(value, loc) + return + o = option(name) + o.setvalue(value, loc) + setvalue(options, name, o) + options_by_order.append(name) + +def setdefault(name, value): + o = getvalue(options, name) + if (o): + o.setdefault(value, loc) + return + print "setdefault: %s not here, setting to %s" % \ + (name, value) + o = option(name) + o.setdefault(value, loc) + setvalue(options, name, o) + options_by_order.append(name) + +# 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 + #fullpath = os.path.join(curdir, path) + #fullpath = path + #setvalue(crt0includes, fullpath, loc) + # oh shoot. Order matters. All right, we'll worry about this + # later. + fullpath = path + if (debug > 2): + print "ADDCRT0: %s\n" % fullpath + crt0includes.append(fullpath) + +def addldscript(path): + global ldscripts + 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:\n" % (fullpath, curdir, path) + ldscripts.append(fullpath) + +def payload(path): + global payloadfile + adduserdefine("PAYLOAD:=%s"%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): + print "add object object_name %s" % 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' + print "addobject %s source %s\n" % (object, source) + setvalue(dict, base, [object, source]) + +def addobject(object_name): + addobjectdriver(objectrules, object_name) + +def adddriver(driver_name): + addobjectdriver(driverrules, driver_name) + +def target(targ_name): + global target_dir + global curpart + print "TARGET loc.file is %s\n" % loc.file() + target_dir = os.path.join(os.path.dirname(loc.file()), targ_name) + print "TARGET dir.loc.file is %s\n" % os.path.dirname(loc.file()) + if not os.path.isdir(target_dir): + print 'Creating directory', target_dir + os.makedirs(target_dir) + print 'Will place Makefile, crt0.S, etc. in ', target_dir + print '%s\n' % loc.file() + board = partobj(target_dir, 0, 'board') + curpart = board + + + +def part(name, path, file): + global curpart,curdir + if (debug): + print "%s " % name + dirstack.append(curdir) + curdir = os.path.join(treetop, 'src', name, path) + newpart = partobj(curdir, curpart, name) + print "PUSH part " , curpart.dir + pstack.push(curpart) + curpart = newpart + # option(parts, name, path) + # open the file, and parse it. +# curpart.option('MAINBOARD_PART_NUMBER', +# os.path.basename(lookup(parts, 'mainboard'))) +# option(options, 'MAINBOARD_VENDOR', os.path.dirname(getvalue(parts, 'mainboard'))) + + doconfigfile(curdir, file) + +def partpop(): + global curpart,curdir + curpart = pstack.pop() + curdir = dirstack.pop() + print "POP PART %s\n" % curpart.dir + +# dodir is like part but there is no new part +def dodir(path, file): + global curdir, treetop + # 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. + if (path[0] == '/'): + fullpath = treetop + '/src/' + path + else: + fullpath = os.path.join(curdir, path) + if (debug): + print "DODIR: path %s, fullpath %s\n" % (path, fullpath) + print "DODIR: curdis %s treetop %s\n" % (curdir, treetop) + dirstack.append(curdir) + curdir = fullpath + file = os.path.join(fullpath, file) + config_file_list.append(file) + doconfigfile(fullpath, file) + curdir = dirstack.pop() + +def ternary(expr, yes, no): + print "ternary %s" % expr + a = tohex(expr) # expr # eval(expr) + print "expr %s a %d yes %d no %d\n"% (expr, a, yes, no) + if (a == 0): + print "Ternary returns %d\n" % yes + return yes + else: + print "Ternary returns %d\n" % no + return no +# atoi is in the python library, but not strtol? Weird! +def tohex(name): + return eval('int(%s)' % name) + +def IsInt( str ): + """ Is the given string an integer?""" + try: + num = int(str) + return 1 + 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) + # highly un-intuitive, need four \! + a = re.sub("\\\\\"", "\"", a) + return a + +def addaction(id, str): + o = getvalue(makebaserules, id) + a = dequote(str) + o.addaction(a) + +def adddep(id, str): + o = getvalue(makebaserules, id) + a = dequote(str) + o.adddependency(a) + +# If the first part of <path> 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] == "/"): + path = path[1:len(path)] + path = "$(TOP)/" + path + return path + +# arch is 'different' ... darn it. +def set_arch(my_arch): + global arch, makebase + global curdir + arch = my_arch + setdefault('ARCH', my_arch) + part('arch', my_arch, 'config/make.base.lb') + + +def mainboard(path): + global mainboard_dir + mainboard_dir = path + full_mainboard_dir = os.path.join(treetop, 'src/mainboard', path) + setdefault('MAINBOARD', full_mainboard_dir) + vendor = re.sub("/.*", "", path) + mainboard_part_number = re.sub("[^/]/", "", path) + setdefault('MAINBOARD_VENDOR', vendor) + setdefault('MAINBOARD_PART_NUMBER', mainboard_part_number) + 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, 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: + o = options[i] + # get the number in hex + v = o.getvalue() + if IsInt(v): + vi = int(v) + s = "export %s:=0x%x\n"% (i, vi) + file.write(s) + else: + file.write("export %s:=%s\n" % (i, v)) + file.write("export VARIABLES := "); + for i in options.keys(): + 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): + 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"); + + # print out all the object dependencies + file.write("\n# object dependencies (objectrules:)\n") + file.write("OBJECTS :=\n") + file.write("DRIVERS :=\n") + for objrule in objectrules.keys(): + obj = objectrules[objrule] + obj_name = obj[0] + obj_source = obj[1] + file.write("OBJECTS-1 += %s\n" % (obj_name)) + + for driverrule in driverrules.keys(): + driver = driverrules[driverrule] + obj_name = driver[0] + obj_source = driver[1] + file.write("DRIVER += %s\n" % (obj_name)) + + # 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") + 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) + + + + + file.write("\nSOURCES=\n") + #for source in sources: + #file.write("SOURCES += %s\n" % source) + + # 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("%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', + 'crt0_includes.h', + 'nsuperio.c', + 'chip.c', + 'LinuxBIOSDoc.config' ]: + file.write("GENERATED += %s\n" % genfile) + + 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 = makeoptions.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(); + + +%% +parser Config: + ignore: r'\s+' + ignore: "#.*?\r?\n" + 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 STR: r'"([^\\"]+|\\.)*"' + token RAWTEXT: r'.*' + token OPTION: 'option' + token MAINBOARD: 'mainboard' + token MAINBOARDINIT: 'mainboardinit' + token EQ: '=' + token END: '$|end' + token TARGET: 'target' + token OBJECT: 'object' + token DRIVER: 'driver' + token NORTHBRIDGE: 'northbridge' + token SOUTHBRIDGE: 'southbridge' + token SUPERIO: 'superio' + token IF: 'if' + token MAKERULE: 'makerule' + token DEP: 'dep' + token ACT: 'act' + token MAKEDEFINE: 'makedefine' + token ADDACTION: 'addaction' + token DEFAULT: 'default' + token INIT: 'init' + token REGISTER: 'register' + token CPU: 'cpu' + token ARCH: 'arch' + token DIR: 'dir' + token LDSCRIPT: 'ldscript' + token PAYLOAD: 'payload' + + # An expression is the sum and difference of factors + rule expr<<V>>: factor<<V>> {{ n = factor }} + ( "[+]" factor<<V>> {{ n = n+factor }} + | "-" factor<<V>> {{ n = n-factor }} + )* {{ return n }} + + # A factor is the product and division of terms + rule factor<<V>>: term<<V>> {{ v = term }} + ( "[*]" term<<V>> {{ v = v*term }} + | "/" term<<V>> {{ v = v/term }} + | "<<" term<<V>> {{ v = v << term }} + | ">=" term<<V>> {{ v = (v < term)}} + )* {{ return v }} + + rule unop<<V>>: "!" ID {{ return ternary(getoption(ID), 1, 0)}} + # A term is a number, variable, or an expression surrounded by parentheses + rule term<<V>>: + NUM {{ return atoi(NUM) }} + | XNUM {{ return tohex(XNUM) }} + | ID {{ return tohex(getoption(ID)) }} + | unop<<V>> {{ return unop }} + | "\\(" expr<<V>> "\\)" {{ return expr }} + + rule option<<C>>: OPTION ID EQ + ( + STR {{ if (C): setoption(ID, dequote(STR)) }} + | term<<[]>> {{ if (C): setoption(ID, term) }} + ) + rule default<<C>>: DEFAULT ID EQ RAWTEXT {{ if (C): setdefault(ID, RAWTEXT) }} + + rule partend<<C>>: partstmts<<C>> END + rule mainboard: MAINBOARD PATH {{mainboard(PATH) }} + partend<<1>> + + rule northbridge<<C>>: NORTHBRIDGE PATH + {{if (C): part('northbridge', PATH, 'Config.lb')}} partend<<C>> + rule superio<<C>>: SUPERIO PATH + {{if (C): part('superio', PATH, 'Config.lb')}} partend<<C>> + rule cpu<<C>>: CPU ID + {{if (C): part('cpu', ID, 'Config.lb')}} partend<<C>> + rule arch<<C>>: ARCH ID + {{if (C): set_arch(ID) }} partend<<C>> + rule southbridge<<C>>: SOUTHBRIDGE PATH + {{if (C): part('southbridge', PATH, 'Config.lb')}} partend<<C>> + + rule mainboardinit<<C>>: + MAINBOARDINIT DIRPATH {{ if (C): addcrt0include(DIRPATH)}} + + rule object<<C>>: OBJECT DIRPATH {{if (C): addobject(DIRPATH)}} + rule driver<<C>>: DRIVER DIRPATH {{if (C): adddriver(DIRPATH)}} + rule dir<<C>>: DIR DIRPATH {{if (C): dodir(DIRPATH, 'Config.lb') }} + + rule ldscript<<C>>: LDSCRIPT DIRPATH {{if (C): addldscript(DIRPATH) }} + rule payload<<C>>: PAYLOAD DIRPATH {{if (C): payload(DIRPATH) }} +# if is a bad id .... + rule iif<<C>>: +# 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. + IF ID {{ c = tohex(getoption(ID)); print "IF %d\n" % c }} (stmt<<c>>)* END + + rule depsacts<<ID, C>>: ( + DEP STR {{ if (C): adddep(ID, STR) }} + | ACT STR {{ if (C): addaction(ID, STR) }} + )* + rule makerule<<C>>: MAKERULE DIRPATH {{ if (C): addrule(DIRPATH) }} + depsacts<<DIRPATH, C>> + rule makedefine<<C>>: MAKEDEFINE RAWTEXT + {{ if (C): adduserdefine(RAWTEXT) }} + rule addaction<<C>>: ADDACTION ID STR + {{ if (C): addaction(ID, STR) }} + rule init<<C>>: INIT STR {{ if (C): curpart.addinit(STR) }} + rule register<<C>>: REGISTER STR {{ if (C): curpart.addregister(STR) }} + +# 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<<C>>: + option<<C>> {{ return option }} + | default<<C>> {{ return default }} + | cpu<<C>> {{ return cpu}} + | arch<<C>> {{ return arch}} + | northbridge<<C>> {{ return northbridge }} + | southbridge<<C>> {{ return southbridge }} + | superio<<C>> {{ return superio }} + | object<<C>> {{ return object }} + | driver<<C>> {{ return driver }} + | mainboardinit<<C>> {{ return mainboardinit }} + | makerule<<C>> {{ return makerule }} + | makedefine<<C>> {{ return makedefine }} + | addaction<<C>> {{ return addaction }} + | init<<C>> {{ return init }} + | register<<C>> {{ return register}} + | iif<<C>> {{ return iif }} + | dir<<C>> {{ return dir}} + | ldscript<<C>> {{ return ldscript}} + | payload<<C>> {{ return payload}} + + rule stmts<<C>>: (stmt<<C>>)* {{ }} + + rule partstmts<<C>>: (stmt<<C>>)* {{ partpop()}} +# need this to get from python to the rules, I think. + + rule pstmts: stmts<<1>> {{ }} + rule target: TARGET DIRPATH {{target(DIRPATH)}} + rule board: target mainboard {{ }} +%% + +def dumptree(part, lvl): + print "DUMPTREE ME is" + part.dumpme(lvl) + # dump the siblings -- actually are there any? not sure + # dump the kids + print "DUMPTREE KIDS are" + for kid in part.children: + dumptree(kid, lvl+1) + print "DONE DUMPTREE" + +def gencode(part): + print "GENCODE ME is" + part.gencode() + # dump the siblings -- actually are there any? not sure + # dump the kids + print "GENCODE KIDS are" + for kid in part.children: + gencode(kid) + print "DONE GENCODE" + + +def doconfigfile(path, file): + if (debug): + print "DOCONFIGFILE", path, " ", file + filename = os.path.join(path, file) + loc.push_file(filename); + parse('pstmts', open(filename, 'r').read()) + +if __name__=='__main__': + from sys import argv + if (len(argv) < 3): + print 'Args: <file> <path to linuxbios>' + + top_config_file = os.path.abspath(sys.argv[1]) + + treetop = os.path.abspath(sys.argv[2]) + + # Set the default locations for config files. + makebase = os.path.join(treetop, "util/config/make.base") + crt0base = os.path.join(treetop, "arch/i386/config/crt0.base") + doxyscriptbase = os.path.join(treetop, "src/config/doxyscript.base") + + # Now read in the customizing script... + loc.push_file(argv[1]); + parse('board', open(argv[1], 'r').read()) + dumptree(curpart, 0) + gencode(curpart) + for i in options.keys(): + o = options[i] + print "key %s @%s: val %s" % (i, o.where(), o.getvalue()) + # crt0 includes + for i in crt0includes: + print "crt0include file %s \n" % (i) + for i in driverrules.keys(): + print "driver file %s \n" % (i) + for i in ldscripts: + print "ldscript file %s\n" % (i) + for i in makebaserules.keys(): + m = makebaserules[i] + print " makerule %s dep %s act %s\n" % (i, m.dependency, m.actions) + writemakefilesettings(target_dir) + writecrt0_includes(target_dir) + writemakefile(target_dir) |