diff options
Diffstat (limited to 'util/sconfig/config.g')
-rw-r--r-- | util/sconfig/config.g | 1028 |
1 files changed, 0 insertions, 1028 deletions
diff --git a/util/sconfig/config.g b/util/sconfig/config.g deleted file mode 100644 index cdc53a89b9..0000000000 --- a/util/sconfig/config.g +++ /dev/null @@ -1,1028 +0,0 @@ -# -*- python -*- -import sys -import os -import re -import string -import types - -import traceback - -warnings = 0 -errors = 0 - -treetop = '' -full_mainboard_path = '' -mainboard_path = '' -romimages = {} -curimage = 0 - -# ----------------------------------------------------------------------------- -# Utility Classes -# ----------------------------------------------------------------------------- - -class stack: - """Used to keep track of the current part or dir""" - class __stack_iter: - def __init__ (self, stack): - self.index = 0 - self.len = len(stack) - self.stack = stack - - def __iter__ (self): - return self - - def next (self): - if (self.index < self.len): - s = self.stack[self.index] - self.index = self.index + 1 - return s - raise StopIteration - - def __init__ (self): - self.stack = [] - - def __len__ (self): - return len(self.stack) - - def __getitem__ (self, i): - return self.stack[i] - - def __iter__ (self): - return self.__stack_iter(self.stack) - - def push(self, part): - self.stack.append(part) - - def pop(self): - try: - return self.stack.pop() - except IndexError: - return 0 - - def tos(self): - try: - return self.stack[-1] - except IndexError: - return 0 - - def empty(self): - return (len(self.stack) == 0) -partstack = stack() - -class debug_info: - none = 0 - gencode = 1 - dumptree = 2 - object = 3 - dict = 4 - statement = 5 - dump = 6 - gengraph = 7 - - def __init__(self, *level): - self.__level = level - - def setdebug(self, *level): - self.__level = level - - def level(self, level): - return level in self.__level - - def info(self, level, str): - if level in self.__level: - print str - -global debug -debug = debug_info(debug_info.none) -#debug = debug_info(debug_info.dumptree) -#debug = debug_info(debug_info.object) -#debug = debug_info(debug_info.gencode) - -# ----------------------------------------------------------------------------- -# Error Handling -# ----------------------------------------------------------------------------- - -def error(string): - """Print error message""" - global errors, loc - errors = errors + 1 - print "===> ERROR: %s" % string - -def fatal(string): - """Print error message and exit""" - error(string) - exitiferrors() - -def warning(string): - """Print warning message""" - global warnings, loc - warnings = warnings + 1 - print "===> WARNING: %s" % string - -def exitiferrors(): - """Exit parser if an error has been encountered""" - if (errors != 0): - sys.exit(1) - -def safe_open(file, mode): - try: - return open(file, mode) - except IOError: - fatal("Could not open file \"%s\"" % file) - -# ----------------------------------------------------------------------------- -# Main classes -# ----------------------------------------------------------------------------- - -class romimage: - """A rom image is the ultimate goal of coreboot""" - def __init__ (self, name): - # name of this rom image - self.name = name - - # instance counter for parts - self.partinstance = 0 - - # chip config files included by the 'config' directive - self.configincludes = {} - - # root of part tree - self.root = 0 - - # Last device built - self.last_device = 0 - - def getname(self): - return self.name - - 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" - else: - return "crt0_includes.h" - - def newformat(self): - return self.useinitincludes - - def numparts(self): - return self.partinstance - - def newpartinstance(self): - i = self.partinstance - self.partinstance = self.partinstance + 1 - return i - - def setroot(self, part): - self.root = part - - def getroot(self): - return self.root - -class partobj: - """A configuration part""" - def __init__ (self, image, dir, parent, part, type_name, instance_name, chip_or_device): - if (parent): - debug.info(debug.object, "partobj dir %s parent %s part %s" \ - % (dir, parent.instance_name, part)) - else: - debug.info(debug.object, "partobj dir %s part %s" \ - % (dir, part)) - - # romimage that is configuring this part - self.image = image - - # links for static device tree - self.children = 0 - self.prev_sibling = 0 - self.next_sibling = 0 - self.prev_device = 0 - self.next_device = 0 - self.chip_or_device = chip_or_device - - # initializers for static device tree - self.registercode = {} - - # part name - self.part = part - - # type name of this part - self.type_name = type_name - - # directory containing part files - self.dir = dir - - # instance number, used to distinguish anonymous - # instances of this part - self.instance = image.newpartinstance() - debug.info(debug.object, "INSTANCE %d" % self.instance) - - # 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 - - # Path to the device - self.path = "" - - # Resources of the device - self.resoruce = "" - self.resources = 0 - - # Enabled state of the device - self.enabled = 1 - - # Flag if I am a duplicate device - self.dup = 0 - - # If there is a chip.h file, we will create an - # include for it. - if (dir): - chiph = os.path.join(dir, "chip.h") - if (os.path.exists(chiph)): - debug.info(debug.object, "%s has chip at %s" % (self, dir)) - self.addconfig(chiph) - - # 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.chipinfo_name = "%s_info_%d" \ - % (self.type_name, self.instance) - else: - self.instance_name = instance_name - self.chipinfo_name = "%s_info_%d" % (self.instance_name, self.instance) - - # Link this part into the device list - if (self.chip_or_device == 'device'): - if (image.last_device): - image.last_device.next_device = self - self.prev_device = image.last_device - image.last_device = self - - # Link this part into the tree - if (parent and (part != 'arch')): - debug.info(debug.gencode, "add to parent") - self.parent = parent - # add current child as my sibling, - # me as the child. - if (parent.children): - debug.info(debug.gencode, "add %s (%d) as sibling" % (parent.children.dir, parent.children.instance)) - youngest = parent.children - while(youngest.next_sibling): - youngest = youngest.next_sibling - youngest.next_sibling = self - self.prev_sibling = youngest - else: - parent.children = self - else: - self.parent = self - - def info(self): - return "%s: %s" % (self.part, self.type) - def type(self): - return self.chip_or_device - - def readable_name(self): - name = "" - name = "%s_%d" % (self.type_name, self.instance) - if (self.chip_or_device == 'chip'): - name = "%s %s %s" % (name, self.part, self.dir) - else: - name = "%s %s" % (name, self.path) - return name - - def graph_name(self): - name = "{ {_dev%d|" % self.instance - if (self.part): - name = "%s%s" % (name, self.part) - else: - name = "%s%s" % (name, self.chip_or_device) - if (self.type_name): - name = "%s}|%s}" % (name, self.type_name) - else: - name = "%s}|%s}" % (name, self.parent.type_name) - return name - - def dumpme(self, lvl): - """Dump information about this part for debugging""" - print "%d: %s" % (lvl, self.readable_name()) - print "%d: part %s" % (lvl, self.part) - print "%d: instance %d" % (lvl, self.instance) - print "%d: chip_or_device %s" % (lvl, self.chip_or_device) - print "%d: dir %s" % (lvl,self.dir) - print "%d: type_name %s" % (lvl,self.type_name) - print "%d: parent: %s" % (lvl, self.parent.readable_name()) - if (self.children): - print "%d: child %s" % (lvl, self.children.readable_name()) - if (self.next_sibling): - print "%d: siblings %s" % (lvl, self.next_sibling.readable_name()) - print "%d: registercode " % lvl - for f, v in self.registercode.items(): - print "\t%s = %s" % (f, v) - print "%d: chipconfig %s" % (lvl, self.chipconfig) - print "\n" - - def firstchilddevice(self): - """Find the first device in the children link.""" - kid = self.children - while (kid): - if (kid.chip_or_device == 'device'): - return kid - else: - kid = kid.children - return 0 - - def firstparentdevice(self): - """Find the first device in the parent link.""" - parent = self.parent - while (parent and (parent.parent != parent) and (parent.chip_or_device != 'device')): - parent = parent.parent - if ((parent.parent != parent) and (parent.chip_or_device != 'device')): - parent = 0 - while(parent and (parent.dup == 1)): - parent = parent.prev_sibling - if (not parent): - fatal("Device %s has no device parent; this is a config file error" % self.readable_name()) - return parent - - def firstparentdevicelink(self): - """Find the first device in the parent link and record which link it is.""" - link = 0 - parent = self.parent - while (parent and (parent.parent != parent) and (parent.chip_or_device != 'device')): - parent = parent.parent - if ((parent.parent != parent) and (parent.chip_or_device != 'device')): - parent = 0 - while(parent and (parent.dup == 1)): - parent = parent.prev_sibling - link = link + 1 - if (not parent): - fatal("Device %s has no device parent; this is a config file error" % self.readable_name()) - return link - - - def firstparentchip(self): - """Find the first chip in the parent link.""" - parent = self.parent - while (parent): - if ((parent.parent == parent) or (parent.chip_or_device == 'chip')): - return parent - else: - parent = parent.parent - fatal("Device %s has no chip parent; this is a config file error" % self.readable_name()) - - def firstsiblingdevice(self): - """Find the first device in the sibling link.""" - sibling = self.next_sibling - while(sibling and (sibling.path == self.path)): - sibling = sibling.next_sibling - if ((not sibling) and (self.parent.chip_or_device == 'chip')): - sibling = self.parent.next_sibling - while(sibling): - if (sibling.chip_or_device == 'device'): - return sibling - else: - sibling = sibling.children - return 0 - - 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.chip_or_device == 'chip'): - return; - else: - if (self.instance): - file.write("struct device %s;\n" \ - % self.instance_name) - else: - file.write("struct device dev_root;\n") - return - # This is pass the second, which is pass number 1 - # this is really just a case statement ... - - if (self.chip_or_device == 'chip'): - if (self.chipconfig): - debug.info(debug.gencode, "gencode: chipconfig(%d)" % \ - self.instance) - file.write("struct %s_config %s" % (self.type_name ,\ - self.chipinfo_name)) - if (self.registercode): - file.write("\t= {\n") - for f, v in self.registercode.items(): - file.write( "\t.%s = %s,\n" % (f, v)) - file.write("};\n") - else: - file.write(";") - file.write("\n") - - if (self.instance == 0): - self.instance_name = "dev_root" - file.write("struct device **last_dev_p = &%s.next;\n" % (self.image.last_device.instance_name)) - file.write("struct device dev_root = {\n") - file.write("\t.ops = &default_dev_ops_root,\n") - file.write("\t.bus = &dev_root.link[0],\n") - file.write("\t.path = { .type = DEVICE_PATH_ROOT },\n") - file.write("\t.enabled = 1,\n\t.links = 1,\n") - file.write("\t.on_mainboard = 1,\n") - file.write("\t.link = {\n\t\t[0] = {\n") - file.write("\t\t\t.dev=&dev_root,\n\t\t\t.link = 0,\n") - file.write("\t\t\t.children = &%s,\n" % self.firstchilddevice().instance_name) - file.write("\t\t},\n") - file.write("\t},\n") - if (self.chipconfig): - file.write("\t.chip_ops = &%s_ops,\n" % self.type_name) - file.write("\t.chip_info = &%s_info_%s,\n" % (self.type_name, self.instance)) - file.write("\t.next = &%s,\n" % self.firstchilddevice().instance_name) - file.write("};\n") - return - - # Don't print duplicate devices, just print their children - if (self.dup): - return - - file.write("struct device %s = {\n" % self.instance_name) - file.write("\t.ops = 0,\n") - file.write("\t.bus = &%s.link[%d],\n" % \ - (self.firstparentdevice().instance_name, \ - self.firstparentdevicelink())) - file.write("\t.path = {%s},\n" % self.path) - file.write("\t.enabled = %d,\n" % self.enabled) - file.write("\t.on_mainboard = 1,\n") - if (self.resources): - file.write("\t.resources = %d,\n" % self.resources) - file.write("\t.resource = {%s\n\t },\n" % self.resource) - file.write("\t.link = {\n"); - links = 0 - bus = self - while(bus and (bus.path == self.path)): - child = bus.firstchilddevice() - if (child or (bus != self) or (bus.next_sibling and (bus.next_sibling.path == self.path))): - file.write("\t\t[%d] = {\n" % links) - file.write("\t\t\t.link = %d,\n" % links) - file.write("\t\t\t.dev = &%s,\n" % self.instance_name) - if (child): - file.write("\t\t\t.children = &%s,\n" %child.instance_name) - file.write("\t\t},\n") - links = links + 1 - if (1): - bus = bus.next_sibling - else: - bus = 0 - file.write("\t},\n") - file.write("\t.links = %d,\n" % (links)) - sibling = self.firstsiblingdevice(); - if (sibling): - file.write("\t.sibling = &%s,\n" % sibling.instance_name) - chip = self.firstparentchip() - if (chip and chip.chipconfig): - file.write("\t.chip_ops = &%s_ops,\n" % chip.type_name) - file.write("\t.chip_info = &%s_info_%s,\n" % (chip.type_name, chip.instance)) - if (self.next_device): - file.write("\t.next=&%s\n" % self.next_device.instance_name) - file.write("};\n") - return - - def addconfig(self, 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""" - if (self.chip_or_device != 'chip'): - fatal("Only chips can have register values") - field = dequote(field) - value = dequote(value) - setdict(self.registercode, field, value) - - def set_enabled(self, enabled): - self.enabled = enabled - - def start_resources(self): - self.resource = "" - self.resources = 0 - - def end_resources(self): - self.resource = "%s" % (self.resource) - - def add_resource(self, type, index, value): - """ Add a resource to a device """ - self.resource = "%s\n\t\t{ .flags=%s, .index=0x%x, .base=0x%x}," % (self.resource, type, index, value) - self.resources = self.resources + 1 - - def set_path(self, path): - self.path = path - if (self.prev_sibling and (self.prev_sibling.path == self.path)): - self.dup = 1 - if (self.prev_device): - self.prev_device.next_device = self.next_device - if (self.next_device): - self.next_device.prev_device = self.prev_device - if (self.image.last_device == self): - self.image.last_device = self.prev_device - self.prev_device = 0 - self.next_device = 0 - - def addpcipath(self, slot, function): - """ Add a relative pci style path from our parent to this device """ - if ((slot < 0) or (slot > 0x1f)): - fatal("Invalid device id") - if ((function < 0) or (function > 7)): - fatal("Invalid pci function %s" % function ) - self.set_path(".type=DEVICE_PATH_PCI,{.pci={ .devfn = PCI_DEVFN(0x%x,%d)}}" % (slot, function)) - - def addpnppath(self, port, device): - """ Add a relative path to a pnp device hanging off our parent """ - if ((port < 0) or (port > 65536)): - fatal("Invalid port") - if ((device < 0) or (device > 0xffff)): - fatal("Invalid device") - self.set_path(".type=DEVICE_PATH_PNP,{.pnp={ .port = 0x%x, .device = 0x%x }}" % (port, device)) - - def addi2cpath(self, device): - """ Add a relative path to a i2c device hanging off our parent """ - if ((device < 0) or (device > 0x7f)): - fatal("Invalid device") - self.set_path(".type=DEVICE_PATH_I2C,{.i2c={ .device = 0x%x }}" % (device)) - - def addapicpath(self, apic_id): - """ Add a relative path to a cpu device hanging off our parent """ - if ((apic_id < 0) or (apic_id > 255)): - fatal("Invalid device") - self.set_path(".type=DEVICE_PATH_APIC,{.apic={ .apic_id = 0x%x }}" % (apic_id)) - - def addpci_domainpath(self, pci_domain): - """ Add a pci_domain number to a chip """ - if ((pci_domain < 0) or (pci_domain > 0xffff)): - fatal("Invalid pci_domain: 0x%x is out of the range 0 to 0xffff" % pci_domain) - self.set_path(".type=DEVICE_PATH_PCI_DOMAIN,{.pci_domain={ .domain = 0x%x }}" % (pci_domain)) - - def addapic_clusterpath(self, cluster): - """ Add an apic cluster to a chip """ - if ((cluster < 0) or (cluster > 15)): - fatal("Invalid apic cluster: %d is out of the range 0 to ff" % cluster) - self.set_path(".type=DEVICE_PATH_APIC_CLUSTER,{.apic_cluster={ .cluster = 0x%x }}" % (cluster)) - - def addcpupath(self, cpu_id): - """ Add a relative path to a cpu device hanging off our parent """ - if ((cpu_id < 0) or (cpu_id > 255)): - fatal("Invalid device") - self.set_path(".type=DEVICE_PATH_CPU,{.cpu={ .id = 0x%x }}" % (cpu_id)) - - - def addcpu_buspath(self, id): - """ Add a cpu_bus to a chip """ - if ((id < 0) or (id > 255)): - fatal("Invalid device") - self.set_path(".type=DEVICE_PATH_CPU_BUS,{.cpu_bus={ .id = 0x%x }}" % (id)) - - -# ----------------------------------------------------------------------------- -# statements -# ----------------------------------------------------------------------------- - -def getdict(dict, name): - if name not in dict.keys(): - debug.info(debug.dict, "Undefined: %s" % name) - return 0 - v = dict.get(name, 0) - debug.info(debug.dict, "getdict %s returning %s" % (name, v)) - return v - -def setdict(dict, name, value): - debug.info(debug.dict, "setdict sets %s to %s" % (name, value)) - if name in dict.keys() and not dict[name] == value: - print "Collision in dict: %s is %s, shall be set to %s" % (name, dict[name], value) - dict[name] = value - - -def addconfig(path): - global partstack - curpart = partstack.tos() - curpart.addconfig(path) - -def addregister(field, value): - global partstack - curpart = partstack.tos() - curpart.addregister(field, value) - -def devicepart(type): - global curimage, partstack - newpart = partobj(curimage, 0, partstack.tos(), type, \ - '', 0, 'device') - #print "Configuring PART %s" % (type) - partstack.push(newpart) - #print " new PART tos is now %s\n" %partstack.tos().info() - # just push TOS, so that we can pop later. - -def part(type, path, file, name): - global curimage, partstack - partdir = os.path.join(type, path) - srcdir = os.path.join(treetop, 'src') - fulldir = os.path.join(srcdir, partdir) - type_name = flatten_name(partdir) - #print "PART(%s, %s, %s, %s)\n" % (type, path, file, name) - newpart = partobj(curimage, fulldir, partstack.tos(), type, \ - type_name, name, 'chip') - #print "Configuring PART %s, path %s" % (type, path) - partstack.push(newpart) - -def partpop(): - global partstack - curpart = partstack.tos() - if (curpart == 0): - fatal("Trying to pop non-existent part") - #print "End PART %s" % curpart.part - oldpart = partstack.pop() - #print "partstack.pop, TOS is now %s\n" % oldpart.info() - -#============================================================================= -# MISC FUNCTIONS -#============================================================================= -def dequote(str): - a = re.sub("^\"", "", str) - a = re.sub("\"$", "", a) - # highly un-intuitive, need four \! - a = re.sub("\\\\\"", "\"", a) - return a - -def flatten_name(str): - a = re.sub("[/-]", "_", str) - return a -%% -parser Config: - ignore: r'\s+' - ignore: "#.*?\r?\n" - - # less general tokens should come first, otherwise they get matched - # by the re's - token COMMENT: 'comment' - token CPU: 'cpu' - token CPU_BUS: 'cpu_bus' - token CHIP: 'chip' - token DEVICE: 'device' - token DEVICE_ID: 'device_id' - token DRQ: 'drq' - token END: 'end' - token EOF: '$' - token EQ: '=' - token FORMAT: 'format' - token IO: 'io' - token IRQ: 'irq' - token MEM: 'mem' - token NEVER: 'never' - token NONE: 'none' - token PMC: 'pmc' - token PRINT: 'print' - token REGISTER: 'register' - token VENDOR_ID: 'vendor_id' - token WRITE: 'write' - token NUM: '[0-9]+' - token HEX_NUM: '[0-9a-fA-F]+' - token HEX_PREFIX: '0x' - # 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 RULE: r'[-a-zA-Z0-9_$()./]+[-a-zA-Z0-9_ $()./]+[-a-zA-Z0-9_$()./]+' - token ID: r'[a-zA-Z_.]+[a-zA-Z0-9_.]*' - token STR: r'"([^\\"]+|\\.)*"' - token RAWTEXT: r'.*' - token ON: 'on' - token OFF: 'off' - token PCI: 'pci' - token PNP: 'pnp' - token I2C: 'i2c' - token APIC: 'apic' - token APIC_CLUSTER: 'apic_cluster' - token CPU: 'cpu' - token CPU_BUS: 'cpu_bus' - token PCI_DOMAIN: 'pci_domain' - - - rule expr: logical {{ l = logical }} - ( "&&" logical {{ l = l and logical }} - | "[|][|]" logical {{ l = l or logical }} - )* {{ return l }} - - rule logical: factor {{ n = factor }} - ( "[+]" factor {{ n = n+factor }} - | "-" factor {{ n = n-factor }} - )* {{ return n }} - - rule factor: term {{ v = term }} - ( "[*]" term {{ v = v*term }} - | "/" term {{ v = v/term }} - | "<<" term {{ v = v << term }} - | ">=" term {{ v = (v < term)}} - )* {{ return v }} - - # A term is a number, variable, or an expression surrounded by parentheses - rule term: NUM {{ return long(NUM, 10) }} - | HEX_PREFIX HEX_NUM {{ return long(HEX_NUM, 16) }} - | ID {{ return lookup(ID) }} - | unop {{ return unop }} - | "\\(" expr "\\)" {{ return expr }} - - rule unop: "!" expr {{ return not(expr) }} - - rule partend<<C>>: (stmt<<C>>)* END {{ if (C): partpop()}} - - # 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... - # DO NOT USE ID AS IT MAY GO AWAY IN THE FUTURE - rule partid: ID {{ return ID }} - | PATH {{ return PATH }} - - rule parttype: CHIP {{ return '' }} - - rule partdef<<C>>: {{ name = 0 }} - parttype partid - [ STR {{ name = dequote(STR) }} - ] {{ if (C): part(parttype, partid, 'Config.lb', name) }} - partend<<C>> - - rule field: STR {{ return STR }} - - rule register<<C>>: REGISTER field '=' STR {{ if (C): addregister(field, STR) }} - - rule enable<<C>>: {{ val = 1 }} - ( ON {{ val = 1 }} - | OFF {{ val = 0 }} - ) {{ if(C): partstack.tos().set_enabled(val) }} - - rule resource<<C>>: {{ type = "" }} - ( IO {{ type = "IORESOURCE_FIXED | IORESOURCE_ASSIGNED | IORESOURCE_IO" }} - | MEM {{ type = "IORESOURCE_FIXED | IORESOURCE_ASSIGNED | IORESOURCE_MEM" }} - | IRQ {{ type = "IORESOURCE_FIXED | IORESOURCE_ASSIGNED | IORESOURCE_IRQ" }} - | DRQ {{ type = "IORESOURCE_FIXED | IORESOURCE_ASSIGNED | IORESOURCE_DRQ" }} - ) - term '=' {{ index = term }} - term {{ value = term }} - {{ if (C): partstack.tos().add_resource(type, index, value) }} - - - rule resources<<C>>: {{ if (C): partstack.tos().start_resources() }} - ( resource<<C>> )* - {{ if (C): partstack.tos().end_resources() }} - - - rule pci<<C>>: PCI {{ if (C): devicepart('pci') }} - - HEX_NUM {{ slot = int(HEX_NUM,16) }} - '.' HEX_NUM {{ function = int(HEX_NUM, 16) }} - {{ if (C): partstack.tos().addpcipath(slot, function) }} - rule pci_domain<<C>>: - PCI_DOMAIN {{ if (C): devicepart('pci_domain') }} - HEX_NUM {{ pci_domain = int(HEX_NUM, 16) }} - {{ if (C): partstack.tos().addpci_domainpath(pci_domain) }} - - rule pnp<<C>>: PNP {{ if (C): devicepart('pnp') }} - HEX_NUM {{ port = int(HEX_NUM,16) }} - '.' HEX_NUM {{ device = int(HEX_NUM, 16) }} - {{ if (C): partstack.tos().addpnppath(port, device) }} - - rule i2c<<C>>: I2C {{ if (C): devicepart('i2c') }} - HEX_NUM {{ device = int(HEX_NUM, 16) }} - {{ if (C): partstack.tos().addi2cpath(device) }} - - rule apic<<C>>: APIC {{ if (C): devicepart('apic') }} - HEX_NUM {{ apic_id = int(HEX_NUM, 16) }} - {{ if (C): partstack.tos().addapicpath(apic_id) }} - - rule apic_cluster<<C>>: APIC_CLUSTER {{ if (C): devicepart('apic_cluster') }} - HEX_NUM {{ cluster = int(HEX_NUM, 16) }} - {{ if (C): partstack.tos().addapic_clusterpath(cluster) }} - - rule cpu<<C>>: CPU {{ if (C): devicepart('cpu') }} - HEX_NUM {{ id = int(HEX_NUM, 16) }} - {{ if (C): partstack.tos().addcpupath(id) }} - - rule cpu_bus<<C>>: CPU_BUS {{ if (C): devicepart('cpu_bus') }} - HEX_NUM {{ id = int(HEX_NUM, 16) }} - {{ if (C): partstack.tos().addcpu_buspath(id) }} - - rule dev_path<<C>>: - pci<<C>> {{ return pci }} - | pci_domain<<C>> {{ return pci_domain }} - | pnp<<C>> {{ return pnp }} - | i2c<<C>> {{ return i2c }} - | apic<<C>> {{ return apic }} - | apic_cluster<<C>> {{ return apic_cluster }} - | cpu<<C>> {{ return cpu }} - | cpu_bus<<C>> {{ return cpu_bus }} - - rule prtval: expr {{ return str(expr) }} - | STR {{ return STR }} - - rule prtlist: prtval {{ el = "%(" + prtval }} - ( "," prtval {{ el = el + "," + prtval }} - )* {{ return el + ")" }} - - rule prtstmt<<C>>: PRINT STR {{ val = STR }} - [ "," prtlist {{ val = val + prtlist }} - ] {{ if (C): print eval(val) }} - - rule device<<C>>: DEVICE dev_path<<C>> - enable<<C>> - resources<<C>> - partend<<C>> - - rule stmt<<C>>: - partdef<<C>> {{ return partdef }} - | prtstmt<<C>> {{ return prtstmt }} - | register<<C>> {{ return register }} - | device<<C>> {{ return device }} - - rule value: STR {{ return dequote(STR) }} - | expr {{ return expr }} - - rule devicetree: partdef<<1>> - EOF {{ return 1 }} - - rule wrstr<<ID>>: STR {{ setwrite(ID, dequote(STR)) }} - -%% - -#============================================================================= -# FILE OUTPUT -#============================================================================= - -def dumptree(part, lvl): - debug.info(debug.dumptree, "DUMPTREE ME is") - print "%s " % part - part.dumpme(lvl) - # dump the siblings -- actually are there any? not sure - # siblings are: - debug.info(debug.dumptree, "DUMPTREE SIBLINGS are") - kid = part.next_sibling - while (kid): - kid.dumpme(lvl) - kid = kid.next_sibling - # dump the kids - debug.info(debug.dumptree, "DUMPTREE KIDS are") - #for kid in part.children: - if (part.children): - dumptree(part.children, lvl+1) - kid = part.next_sibling - while (kid): - if (kid.children): - dumptree(kid.children, lvl + 1) - kid = kid.next_sibling - debug.info(debug.dumptree, "DONE DUMPTREE") - -def writecode(image): - filename = os.path.join(img_dir, "static.c") - print " SCONFIG ", join(filename.split('/')[-4:], '/') - file = safe_open(filename, 'w+') - file.write("#include <device/device.h>\n") - file.write("#include <device/pci.h>\n") - for path in image.getconfigincludes().values(): - file.write("#include \"%s\"\n" % path) - file.write("\n/* pass 0 */\n") - gencode(image.getroot(), file, 0) - file.write("\n/* pass 1 */\n") - gencode(image.getroot(), file, 1) - file.close() - -def gencode(part, file, pass_num): - debug.info(debug.gencode, "GENCODE ME is") - part.gencode(file, pass_num) - # dump the siblings -- actually are there any? not sure - debug.info(debug.gencode, "GENCODE SIBLINGS are") - kid = part.next_sibling - while (kid): - kid.gencode(file, pass_num) - kid = kid.next_sibling - # now dump the children - debug.info(debug.gencode, "GENCODE KIDS are") - if (part.children): - gencode(part.children, file, pass_num) - kid = part.next_sibling - while (kid): - if (kid.children): - gencode(kid.children, file, pass_num) - kid = kid.next_sibling - debug.info(debug.gencode, "DONE GENCODE") - -def writegraph(image): - filename = os.path.join(img_dir, "static.dot") - print " SCONFIG ", join(filename.split('/')[-4:], '/') - file = safe_open(filename, 'w+') - file.write("digraph devicetree {\n") - file.write(" rankdir=LR\n") - genranks(image.getroot(), file, 0) - gennodes(image.getroot(), file) - gengraph(image.getroot(), file) - file.write("}\n") - file.close() - -def genranks(part, file, level): - #file.write(" # Level %d\n" % level ) - file.write(" { rank = same; \"dev_%s_%d\"" % (part.type_name,part.instance )) - sib = part.next_sibling - while (sib): - file.write("; \"dev_%s_%d\"" % (sib.type_name, sib.instance)) - sib = sib.next_sibling - file.write("}\n" ) - # now dump the children - if (part.children): - genranks(part.children, file, level + 1) - - kid = part.next_sibling - while (kid): - if (kid.children): - genranks(kid.children, file, level + 1) - kid = kid.next_sibling - - -def gennodes(part, file): - file.write(" dev_%s_%d[shape=record, label=\"%s\"];\n" % (part.type_name,part.instance,part.graph_name() )) - sib = part.next_sibling - while (sib): - file.write(" dev_%s_%d[shape=record, label=\"%s\"];\n" % (sib.type_name,sib.instance,sib.graph_name() )) - sib = sib.next_sibling - # now dump the children - if (part.children): - gennodes(part.children, file) - - kid = part.next_sibling - while (kid): - if (kid.children): - gennodes(kid.children, file) - kid = kid.next_sibling - - -def gengraph(part, file): - if (part.parent != part): - file.write(" dev_%s_%d -> dev_%s_%d;\n" % \ - (part.parent.type_name, part.parent.instance, \ - part.type_name, part.instance )) - sib = part.next_sibling - while (sib): - file.write(" dev_%s_%d -> dev_%s_%d;\n" % \ - (sib.parent.type_name, sib.parent.instance, \ - sib.type_name, sib.instance )) - sib = sib.next_sibling - - kid = part.next_sibling - while (kid): - if (kid.children): - gengraph(kid.children, file) - kid = kid.next_sibling - - if (part.children): - gengraph(part.children, file) - -#============================================================================= -# MAIN PROGRAM -#============================================================================= -if __name__=='__main__': - from sys import argv - if (len(argv) < 4): - fatal("Args: <file> <path to coreboot> <output-dir>") - - file = "devicetree.cb" - partdir = os.path.join("mainboard", sys.argv[1]) - treetop = argv[2] - srcdir = os.path.join(treetop, 'src') - fulldir = os.path.join(srcdir, partdir) - type_name = flatten_name(partdir) - config_file = os.path.join(fulldir, file) - - curimage = romimage("new") - image = curimage - - newpart = partobj(curimage, fulldir, partstack.tos(), 'mainboard', \ - 'mainboard', 0, 'chip') - #print "Configuring PART %s, path %s" % (type, path) - image.setroot(newpart); - partstack.push(newpart) - - fp = safe_open(config_file, 'r') - if (not parse('devicetree', fp.read())): - fatal("Could not parse file") - partstack.pop() - - img_dir = argv[3] - - #debug.info(debug.dumptree, "DEVICE TREE:") - #dumptree(curimage.getroot(), 0) - - writecode(image) - writegraph(image) - - sys.exit(0) |