Added support for naming instances of parts. This is to allow arbitrary

device arrangement that can be statically configured during boot.


git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1058 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
Greg Watson 2003-07-28 21:35:14 +00:00
parent f4ade7a0a1
commit b265254e1c
1 changed files with 170 additions and 90 deletions

View File

@ -192,23 +192,59 @@ def safe_open(file, mode):
class romimage:
"""A rom image is the ultimate goal of linuxbios"""
def __init__ (self, name):
# name of this rom image
self.name = name
# set by 'arch' directive
self.arch = ''
# set by 'payload' directive
self.payload = ''
# set by 'init' directive
self.initfile = ''
# make rules added by 'makerule' directive
self.makebaserules = {}
# object files added by 'object' directive
self.objectrules = {}
# init object files added by 'initobject' directive
self.initobjectrules = {}
# driver files added by 'drive' directive
self.driverrules = {}
# loader scripts added by 'ldscript' directive
self.ldscripts = []
# user defines added by 'makedefine' directive
self.userdefines = []
# files to be included in crt0.S
self.initincludes = {}
self.initincludesorder = [] # need to preserve order
self.useinitincludes = 0 # transitional
# as above, but order is preserved
self.initincludesorder = []
# transitional flag to support old crtinclude format
self.useinitincludes = 0
# instance counter for parts
self.partinstance = 0
# chip config files included by the 'config' directive
self.configincludes = {}
# root of part tree
self.root = 0
# name of target directory specified by 'target' directive
self.target_dir = ''
self.values = {} # values of options set in romimage
# option values set in rom image
self.values = {}
def getname(self):
return self.name
@ -352,6 +388,12 @@ class romimage:
return o
fatal("No such init include \"%s\"" % path);
def addconfiginclude(self, part, path):
setdict(self.configincludes, part, path)
def getconfigincludes(self):
return self.configincludes
def getincludefilename(self):
if (self.useinitincludes):
return "crt0.S"
@ -528,26 +570,62 @@ class option_value:
class partobj:
"""A configuration part"""
def __init__ (self, image, dir, parent, type, name):
debug.info(debug.object, "partobj dir %s parent %s type %s" %(dir,parent,type))
def __init__ (self, image, dir, parent, part, type_name, instance_name):
debug.info(debug.object, "partobj dir %s parent %s part %s" \
% (dir, parent, part))
# romimage that is configuring this part
self.image = image
# links for static device tree
self.children = 0
self.siblings = 0
# list of init code files
self.initcode = []
# initializers for static device tree
self.registercode = {}
# sibling is not a list.
self.type = type
# part name
self.part = part
# type name of this part
self.type_name = type_name
# object files needed to build this part
self.objects = []
# directory containg part files
self.dir = dir
self.irq = 0
# instance number, used to distinguish anonymous
# instances of this part
self.instance = image.newpartinstance()
self.flatten_name = flatten_name(os.path.join(type, name))
debug.info(debug.object, "INSTANCE %d" % self.instance)
self.devfn = 0
self.private = 0
# Options used by this part
self.uses_options = {}
# Name of chip config file (0 if not needed)
self.chipconfig = 0
# Flag to indicate that we have generated type
# definitions for this part (only want to do it once)
self.done_types = 0
# If no instance name is supplied then generate
# a unique name
if (instance_name == 0):
self.instance_name = self.type_name + \
"_dev%d" % self.instance
self.config_name = "%s_config_%d" \
% (self.type_name, self.instance)
else:
self.instance_name = instance_name
self.config_name = "%s_config" % self.instance_name
# Link this part into the tree
if (parent):
debug.info(debug.gencode, "add to parent")
self.parent = parent
@ -561,11 +639,12 @@ class partobj:
self.parent = self
def dumpme(self, lvl):
print "%d: type %s" % (lvl, self.type)
"""Dump information about this part for debugging"""
print "%d: part %s" % (lvl, self.part)
print "%d: instance %d" % (lvl, self.instance)
print "%d: dir %s" % (lvl,self.dir)
print "%d: flatten_name %s" % (lvl,self.flatten_name)
print "%d: parent %s" % (lvl,self.parent.type)
print "%d: name %s" % (lvl,self.name)
print "%d: parent %s" % (lvl,self.parent.part)
print "%d: parent dir %s" % (lvl,self.parent.dir)
if (self.children):
print "%d: child %s" % (lvl, self.children.dir)
@ -579,16 +658,22 @@ class partobj:
print " %s = %s" % (f, v)
print "\n"
def gencode(self, file):
def gencode(self, file, pass_num):
"""Generate static initalizer code for this part. Two passes
are used - the first generates type information, and the second
generates instance information"""
if (pass_num == 0):
if (self.instance):
file.write("struct chip %s;\n" \
% self.instance_name)
else:
file.write("struct chip static_root;\n")
return
if (self.chipconfig):
debug.info(debug.gencode, "gencode: chipconfig(%d)" % self.instance)
file.write("#include \"%s\"\n" % os.path.join(self.dir, self.chipconfig))
file.write("extern struct chip_control %s_control;\n" % \
self.flatten_name)
file.write("struct %s_config %s_config_%d" % (\
self.flatten_name ,\
self.flatten_name , \
self.instance))
debug.info(debug.gencode, "gencode: chipconfig(%d)" % \
self.instance)
file.write("struct %s_config %s" % (self.type_name ,\
self.config_name))
if (self.registercode):
file.write("\t= {\n")
for f, v in self.registercode.items():
@ -598,46 +683,55 @@ class partobj:
file.write(";")
file.write("\n");
if (self.instance):
file.write("struct chip static_dev%d = {\n" % self.instance)
file.write("struct chip %s = {\n" % self.instance_name)
else:
file.write("struct chip static_root = {\n")
file.write("/* %s %s */\n" % (self.type, self.dir))
#file.write(" .devfn = %d,\n" % self.devfn)
file.write("/* %s %s */\n" % (self.part, self.dir))
if (self.siblings):
debug.info(debug.gencode, "gencode: siblings(%d)" % self.siblings.instance)
file.write(" .next = &static_dev%d,\n" % self.siblings.instance)
debug.info(debug.gencode, "gencode: siblings(%d)" \
% self.siblings.instance)
file.write(" .next = &%s,\n" \
% self.siblings.instance_name)
else:
file.write(" .next = 0,\n")
if (self.children):
debug.info(debug.gencode, "gencode: children(%d)" % self.children.instance)
file.write(" .children = &static_dev%d,\n" % \
self.children.instance)
if (self.private):
file.write(" .private = private%d,\n" % self.instance)
debug.info(debug.gencode, "gencode: children(%d)" \
% self.children.instance)
file.write(" .children = &%s,\n" \
% self.children.instance_name)
else:
file.write(" .children = 0,\n")
if (self.chipconfig):
# set the pointer to the structure for all this
# type of part
file.write(" .control= &%s_control,\n" % \
self.flatten_name )
self.type_name )
# generate the pointer to the isntance
# of the chip struct
file.write(" .chip_info = (void *) &%s_config_%d,\n" %\
(self.flatten_name, self.instance ))
file.write(" .chip_info = (void *) &%s,\n" \
% self.config_name)
else:
file.write(" .control= 0,\n")
file.write(" .chip_info= 0,\n")
file.write("};\n")
def irq(self, irq):
self.irq = irq
def addinit(self, code):
"""Add init file to this part"""
self.initcode.append(code)
def addconfig(self, path):
self.chipconfig = path
"""Add chip config file to this part"""
self.chipconfig = os.path.join(self.dir, path)
self.image.addconfiginclude(self.type_name, self.chipconfig)
def addregister(self, field, value):
"""Register static initialization information"""
field = dequote(field)
value = dequote(value)
setdict(self.registercode, field, value)
def usesoption(self, name):
"""Declare option that can be used by this part"""
global global_options
o = getdict(global_options, name)
if (o == 0):
@ -709,7 +803,7 @@ def getoption(name, image):
def setoption(name, value):
global loc, global_options, global_option_values, curimage
curpart = partstack.tos()
if (curpart and curpart.type != 'mainboard'):
if (curpart and curpart.part != 'mainboard'):
fatal("Options may only be set in top-level and mainboard configuration files")
o = getdict(global_uses_options, name)
if (o == 0):
@ -935,7 +1029,7 @@ def mainboard(path):
setoption('MAINBOARD_VENDOR', vendor)
setoption('MAINBOARD_PART_NUMBER', part_number)
dodir('/config', 'Config.lb')
part('mainboard', path, 'Config.lb')
part('mainboard', path, 'Config.lb', 0)
curimage.setroot(partstack.tos())
partpop()
@ -968,13 +1062,15 @@ def target(name):
print "Will place Makefile, crt0.S, etc. in %s" % target_dir
def part(name, path, file):
def part(type, path, file, name):
global curimage, dirstack, partstack
partdir = os.path.join(name, path)
partdir = os.path.join(type, path)
srcdir = os.path.join(treetop, 'src')
fulldir = os.path.join(srcdir, partdir)
newpart = partobj(curimage, fulldir, partstack.tos(), name, path)
print "Configuring PART %s, path %s" % (name, path)
type_name = flatten_name(os.path.join(type, path))
newpart = partobj(curimage, fulldir, partstack.tos(), type, \
type_name, name)
print "Configuring PART %s, path %s" % (type, path)
partstack.push(newpart)
dirstack.push(fulldir)
doconfigfile(srcdir, partdir, file)
@ -984,7 +1080,7 @@ def partpop():
curpart = partstack.pop()
if (curpart == 0):
fatal("Trying to pop non-existent part")
print "End PART %s" % curpart.type
print "End PART %s" % curpart.part
# Warn if options are used without being set in this part
for i in curpart.uses_options.keys():
if (not isset(i, curpart)):
@ -1030,12 +1126,12 @@ def adddep(id, str):
global curimage
curimage.addmakedepend(id, str)
def set_arch(my_arch):
def setarch(my_arch):
"""arch is 'different' ... darn it."""
global curimage
curimage.setarch(my_arch)
setoption('ARCH', my_arch)
part('arch', my_arch, 'Config.lb')
part('arch', my_arch, 'Config.lb', 0)
def doconfigfile(path, confdir, file):
rname = os.path.join(confdir, file)
@ -1190,30 +1286,26 @@ parser Config:
rule partend<<C>>: (stmt<<C>>)* END {{ if (C): partpop()}}
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>>
# This is needed because the legacy cpu command could not distinguish
# between cpu vendors. It should just be PATH, but getting this change
# into the source tree will be tricky...
rule cpuid: ID {{ return ID }}
# DO NOT USE ID AS IT MAY GO AWAY IN THE FUTURE
rule partid: ID {{ return ID }}
| PATH {{ return PATH }}
rule cpu<<C>>: CPU cpuid {{ if (C): part('cpu', cpuid, 'Config.lb') }}
rule parttype: NORTHBRIDGE {{ return 'northbridge' }}
| SUPERIO {{ return 'superio' }}
| PMC {{ return 'pmc' }}
| SOUTHBRIDGE {{ return 'southbridge' }}
| CPU {{ return 'cpu' }}
rule partdef<<C>>: {{ name = 0 }}
parttype partid
[ STR {{ name = dequote(STR) }}
] {{ if (C): part(parttype, partid, 'Config.lb', name) }}
partend<<C>>
rule pmc<<C>>: PMC PATH {{ if (C): part('pmc', PATH, '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')}}
rule arch<<C>>: ARCH ID {{ if (C): setarch(ID) }}
partend<<C>>
rule mainboardinit<<C>>:
@ -1277,7 +1369,6 @@ parser Config:
rule stmt<<C>>: arch<<C>> {{ return arch}}
| addaction<<C>> {{ return addaction }}
| config<<C>> {{ return config}}
| cpu<<C>> {{ return cpu}}
| dir<<C>> {{ return dir}}
| driver<<C>> {{ return driver }}
| iif<<C>> {{ return iif }}
@ -1288,14 +1379,11 @@ parser Config:
| mainboardinit<<C>> {{ return mainboardinit }}
| makedefine<<C>> {{ return makedefine }}
| makerule<<C>> {{ return makerule }}
| northbridge<<C>> {{ return northbridge }}
| object<<C>> {{ return object }}
| option<<C>> {{ return option }}
| pmc<<C>> {{ return pmc}}
| partdef<<C>> {{ return partdef }}
| prtstmt<<C>> {{ return prtstmt}}
| register<<C>> {{ return register}}
| southbridge<<C>> {{ return southbridge }}
| superio<<C>> {{ return superio }}
# ENTRY for parsing Config.lb file
rule cfgfile: (uses<<1>>)*
@ -1682,38 +1770,30 @@ def writecode(image):
filename = os.path.join(img_dir, "static.c")
print "Creating", filename
file = safe_open(filename, 'w+')
# gen all the forward references
i = 0
file.write("#include <device/chip.h>\n")
file.write("struct chip ")
while (i <= image.numparts()):
if (i):
file.write(", static_dev%d"% i)
else:
file.write("static_root")
i = i + 1
file.write(";\n")
gencode(image.getroot(), file)
for path in image.getconfigincludes().values():
file.write("#include \"%s\"\n" % path)
gencode(image.getroot(), file, 0)
gencode(image.getroot(), file, 1)
file.close()
def gencode(part, file):
def gencode(part, file, pass_num):
debug.info(debug.gencode, "GENCODE ME is")
part.gencode(file)
part.gencode(file, pass_num)
# dump the siblings -- actually are there any? not sure
debug.info(debug.gencode, "GENCODE SIBLINGS are")
kid = part.siblings
while (kid):
kid.gencode(file)
kid.gencode(file, pass_num)
kid = kid.siblings
# now dump the children
debug.info(debug.gencode, "GENCODE KIDS are")
if (part.children):
gencode(part.children, file)
gencode(part.children, file, pass_num)
kid = part.siblings
while (kid):
if (kid.children):
gencode(kid.children, file)
gencode(kid.children, file, pass_num)
kid = kid.siblings
debug.info(debug.gencode, "DONE GENCODE")