First shot at factoring SMM code into generic parts and southbridge specific
[coreboot.git] / util / newconfig / config.g
index c5b13ca62284e8115c0fd75ce99c196e5eacd52b..294d4072161b31e064ca9b0c4b1113953a1cdf94 100644 (file)
@@ -1,3 +1,4 @@
+# -*- python -*-
 import sys
 import os
 import re
@@ -12,6 +13,8 @@ errors = 0
 target_dir = ''
 target_name = ''
 treetop = ''
+full_mainboard_path = ''
+mainboard_path = ''
 global_options = {}
 global_options_by_order = []
 global_option_values = {}
@@ -164,11 +167,11 @@ def error(string):
         global errors, loc
        errors = errors + 1
         print "===> ERROR: %s" % string
+        print "%s" % loc
 
 def fatal(string):      
        """Print error message and exit"""
        error(string)
-        print "%s" % loc
         exitiferrors()
 
 def warning(string):
@@ -179,7 +182,7 @@ def warning(string):
 
 def notice(string):
        """Print notice message"""
-        print "===> NOTE: %s" % string
+       #print "===> NOTE: %s" % string
 
 def exitiferrors():
        """Exit parser if an error has been encountered"""
@@ -197,7 +200,7 @@ def safe_open(file, mode):
 # -----------------------------------------------------------------------------
 
 class romimage:
-       """A rom image is the ultimate goal of linuxbios"""
+       """A rom image is the ultimate goal of coreboot"""
        def __init__ (self, name):
                # name of this rom image
                self.name = name
@@ -220,9 +223,12 @@ class romimage:
                # init object files added by 'initobject' directive
                self.initobjectrules = {}
 
-               # driver files added by 'drive' directive
+               # driver files added by 'driver' directive
                self.driverrules = {}
 
+               # smm object files added by 'smmobject' directive
+               self.smmobjectrules = {}
+
                # loader scripts added by 'ldscript' directive
                self.ldscripts = []
 
@@ -256,6 +262,9 @@ class romimage:
                # exported options
                self.exported_options = []
 
+               # Last device built
+               self.last_device = 0
+
        def getname(self):
                return self.name
 
@@ -338,6 +347,9 @@ class romimage:
        def adddriverrule(self, name):
                self.addobjectdriver(self.driverrules, name)
 
+       def addsmmobjectrule(self, name):
+               self.addobjectdriver(self.smmobjectrules, name)
+
        def getinitobjectrules(self):
                return self.initobjectrules
 
@@ -365,6 +377,15 @@ class romimage:
                        return o
                fatal("No such driver rule \"%s\"" % name)
 
+       def getsmmobjectrules(self):
+               return self.smmobjectrules
+
+       def getsmmobjectrule(self, name):
+               o = getdict(self.smmobjectrules, name)
+               if (o):
+                       return o
+               fatal("No such smm object rule \"%s\"" % name)
+
        def addldscript(self, path):
                self.ldscripts.append(path)
 
@@ -514,6 +535,11 @@ class option:
        def getformat(self):
                return self.format
 
+       def setused(self):
+               if (self.exportable):
+                       self.exported = 1
+               self.used = 1
+
        def setwrite(self, part):
                self.write.append(part)
 
@@ -560,7 +586,7 @@ class option_value:
 
 class partobj:
        """A configuration part"""
-       def __init__ (self, image, dir, parent, part, type_name, instance_name, link):
+       def __init__ (self, image, dir, parent, part, type_name, instance_name, chip_or_device):
                debug.info(debug.object, "partobj dir %s parent %s part %s" \
                                % (dir, parent, part))
 
@@ -569,7 +595,11 @@ class partobj:
 
                # links for static device tree
                self.children = 0
-               self.siblings = 0
+               self.prev_sibling = 0
+               self.next_sibling = 0
+               self.prev_device = 0
+               self.next_device = 0
+               self.chip_or_device = chip_or_device
 
                # list of init code files
                self.initcode = []
@@ -607,24 +637,36 @@ class partobj:
                # Path to the device
                self.path = ""
 
-                # Link from parent device
-                if ((link < 0) or (link > 16)):
-                       fatal("Invalid link")
-                self.link = link
-               
+               # Resources of the device
+               self.resoruce = ""
+               self.resources = 0
+
+               # Enabled state of the device
+               self.enabled = 1
+
+               # Flag if I am a dumplicate device
+               self.dup = 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.chipinfo_name = "%s_info_%d" \
                                        % (self.type_name, self.instance)
                else:
                        self.instance_name = instance_name
-                       self.config_name = "%s_config" % self.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):
+               if (parent and (part != 'arch')):
                        debug.info(debug.gencode, "add to parent")
                        self.parent   = parent
                        # add current child as my sibling, 
@@ -632,26 +674,43 @@ class partobj:
                        if (parent.children):
                                debug.info(debug.gencode, "add %s (%d) as sibling" % (parent.children.dir, parent.children.instance))
                                youngest = parent.children
-                               while(youngest.siblings):
-                                       youngest = youngest.siblings
-                               youngest.siblings = self
+                               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 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: name %s" % (lvl,self.name)
-               print "%d: parent %s" % (lvl,self.parent.part)
-               print "%d: parent dir %s" % (lvl,self.parent.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.dir)
-               if (self.siblings):
-                       print "%d: siblings %s" % (lvl, self.siblings.dir)
+                       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: initcode " % lvl
                for i in self.initcode:
                        print "\t%s" % i
@@ -660,66 +719,168 @@ class partobj:
                        print "\t%s = %s" % (f, v)
                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.instance):
-                               file.write("struct chip %s;\n" \
-                                       % self.instance_name)
+                       if (self.chip_or_device == 'chip'):
+                               return;
                        else:
-                               file.write("struct chip static_root;\n")
+                               if (self.instance):
+                                       file.write("struct device %s;\n" \
+                                               % self.instance_name)
+                               else:
+                                       file.write("struct device dev_root;\n")
                        return
-               if (self.chipconfig):
-                       debug.info(debug.gencode, "gencode: chipconfig(%d)" % \
+               # 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.config_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("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:
-                               file.write(";")
-                       file.write("\n")
-               if (self.instance):
-                       file.write("struct chip %s = {\n" % self.instance_name)
-               else:
-                       file.write("struct chip static_root = {\n")
-               file.write("\t/* %s %s */\n" % (self.part, self.dir))
-                file.write("\t.link = %d,\n" % (self.link))
-               if (self.path != ""):
-                       file.write("\t.path = { %s\n\t},\n" % (self.path) )
-               if (self.siblings):
-                       debug.info(debug.gencode, "gencode: siblings(%d)" \
-                               % self.siblings.instance)
-                       file.write("\t.next = &%s,\n" \
-                               % self.siblings.instance_name)
-               else:
-                       file.write("\t.next = 0,\n")
-               if (self.children):
-                       debug.info(debug.gencode, "gencode: children(%d)" \
-                               % self.children.instance)
-                       file.write("\t.children = &%s,\n" \
-                               % self.children.instance_name)
-               else:
-                       file.write("\t.children = 0,\n")
-               if (self.chipconfig):
-                       # set the pointer to the structure for all this
-                       # type of part
-                       file.write("\t.control= &%s_control,\n" % \
-                                       self.type_name )
-                       # generate the pointer to the isntance
-                       # of the chip struct
-                       file.write("\t.chip_info = (void *) &%s,\n" \
-                                       % self.config_name)
-               else:
-                       file.write("\t.control= 0,\n")
-                       file.write("\t.chip_info= 0,\n")
+                               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 addinit(self, code):
                """Add init file to this part"""
                self.initcode.append(code)
@@ -731,47 +892,93 @@ class partobj:
 
        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.path = "%s, .resource={" % (self.path)
+               self.resource = ""
+               self.resources = 0
 
        def end_resources(self):
-               self.path = "%s}}," % (self.path)
+               self.resource = "%s" % (self.resource)
 
        def add_resource(self, type, index, value):
                """ Add a resource to a device """
-               self.path = "%s\n\t\t\t{ .flags=%s, .index=0x%x, .base=0x%x}," % (self.path, type, index, value)
-               
-               
+               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, enable, bus, slot, function):
+       def addpcipath(self, slot, function):
                """ Add a relative pci style path from our parent to this device """
-               if ((bus < 0) or (bus > 255)):
-                       fatal("Invalid bus")
                if ((slot < 0) or (slot > 0x1f)):
                        fatal("Invalid device id")
                if ((function < 0) or (function > 7)):
-                       fatal("Invalid function")
-               self.path = "%s\n\t\t{ .enabled = %d, .path = {.type=DEVICE_PATH_PCI,.u={.pci={ .bus = 0x%x, .devfn = PCI_DEVFN(0x%x,%d)}}}" % (self.path, enable, bus, slot, function)
+                       fatal("Invalid pci function %s" % function )
+               self.set_path(".type=DEVICE_PATH_PCI,.u={.pci={ .devfn = PCI_DEVFN(0x%x,%d)}}" % (slot, function))
 
-       def addpnppath(self, enable, port, device):
+       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 > 0xff)):
+               if ((device < 0) or (device > 0xffff)):
                        fatal("Invalid device")
-               self.path = "%s\n\t\t{ .enabled = %d, .path={.type=DEVICE_PATH_PNP,.u={.pnp={ .port = 0x%x, .device = 0x%x }}}" % (self.path, enable, port, device)
+               self.set_path(".type=DEVICE_PATH_PNP,.u={.pnp={ .port = 0x%x, .device = 0x%x }}" % (port, device))
                
-       def addi2cpath(self, enabled, 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.path = "%s\n\t\t{ .enabled = %d, .path = {.type=DEVICE_PATH_I2C,.u={.i2c={ .device = 0x%x }}} " % (self.path, enable, device)
+               self.set_path(".type=DEVICE_PATH_I2C,.u={.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,.u={.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,.u={.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,.u={.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,.u={.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,.u={.cpu_bus={ .id = 0x%x }}" % (id))
+    
        def usesoption(self, name):
                """Declare option that can be used by this part"""
                global global_options
@@ -782,10 +989,7 @@ class partobj:
                if (o1):
                        return
                setdict(self.uses_options, name, o)
-
-       def exportoption(self, op):
-               """Export option that is used by this part"""
-               exportoption(op, self.image.exported_options)
+               exportoption(o, self.image.exported_options)
 
 # -----------------------------------------------------------------------------
 #                    statements 
@@ -833,7 +1037,10 @@ def newoptionvalue(name, image):
 
 def getoptionvalue(name, op, image):
        global global_option_values
+       #print "getoptionvalue name %s op %s image %s\n" % (name, op,image)
        if (op == 0):
+               # we want to debug config files, not the config tool, so no:
+               # print_stack() 
                fatal("Option %s undefined (missing use command?)" % name)
        if (image):
                v = getdict(image.getvalues(), name)
@@ -848,11 +1055,14 @@ def getoption(name, image):
 
        global global_uses_options, alloptions, curimage
 
+       #print "getoption: name %s image %s alloptions %s curimage %s\n\n" % (name, image, alloptions, curimage)
        curpart = partstack.tos()
        if (alloptions):
                o = getdict(global_options, name)
        elif (curpart):
                o = getdict(curpart.uses_options, name)
+               if (o == 0):
+                       print "curpart.uses_options is %s\n" % curpart.uses_options
        else:
                o = getdict(global_uses_options, name)
        v = getoptionvalue(name, o, image)
@@ -872,12 +1082,6 @@ def getoption(name, image):
        exitiferrors()
        return val
 
-def exportoption(op, exported_options):
-       if (not op.isexportable()):
-               return
-       if (not op in exported_options):
-               exported_options.append(op)
-
 def setoption(name, value, imp):
        """Set an option from within a configuration file. Normally this
        is only permitted in the target (top level) configuration file.
@@ -903,19 +1107,19 @@ def setoption(name, value, imp):
        if (v == 0):
                v = newoptionvalue(name, curimage)
        v.setvalue(value)
-       if (curpart):
-               curpart.exportoption(o)
-       else:
-               exportoption(o, global_exported_options)
+
+def exportoption(op, exported_options):
+       if (not op.isexportable()):
+               return
+       if (not op in exported_options):
+               exported_options.append(op)
 
 def setdefault(name, value, isdef):
        """Set the default value of an option from within a configuration 
        file. This is permitted from any configuration file, but will
        result in a warning if the default is set more than once.
        If 'isdef' is set, we're defining the option in Options.lb so
-       there is no need for 'uses'.
-       Note also that changing an options default value will export
-       the option, if it is exportable."""
+       there is no need for 'uses'."""
 
        global loc, global_options, curimage
 
@@ -938,12 +1142,6 @@ def setdefault(name, value, isdef):
        if (v == 0):
                v = newoptionvalue(name, image)
        v.setdefault(value)
-       if (isdef):
-               return
-       if (curpart):
-               curpart.exportoption(o)
-       else:
-               exportoption(o, global_exported_options)
 
 def setnodefault(name):
        global loc, global_options
@@ -1047,6 +1245,7 @@ def usesoption(name):
        if (o1):
                return
        setdict(global_uses_options, name, o)
+       exportoption(o, global_exported_options)
 
 def validdef(name, defval):
        global global_options
@@ -1060,12 +1259,12 @@ def validdef(name, defval):
        if ((defval & 4) != 4):
            fatal("Must specify comment for option %s" % name)
 
-def loadoptions():
-       file = os.path.join('src', 'config', 'Options.lb')
+def loadoptions(path, file, rule):
+       file = os.path.join('src', path, file)
        optionsfile = os.path.join(treetop, file)
        fp = safe_open(optionsfile, 'r')
        loc.push(file)
-       if (not parse('options', fp.read())):
+       if (not parse(rule, fp.read())):
                fatal("Could not parse file")
        loc.pop()
 
@@ -1115,7 +1314,9 @@ def payload(path):
 
 def startromimage(name):
        global romimages, curimage, target_dir, target_name
-       print "Configuring ROMIMAGE %s" % name
+       curpart = partstack.tos()
+       print "Configuring ROMIMAGE %s Curimage %s" % (name, curimage)
+       print "Curpart is %s\n" % curpart
        o = getdict(romimages, name)
        if (o):
                fatal("romimage %s previously defined" % name)
@@ -1124,22 +1325,45 @@ def startromimage(name):
        #o = partobj(curimage, target_dir, 0, 'board', target_name)
        #curimage.setroot(o)
        setdict(romimages, name, curimage)
+       dodir('/config', 'Config.lb')
 
 def endromimage():
        global curimage
+       mainboard()
        print "End ROMIMAGE"
        curimage = 0
        #curpart = 0
 
-def mainboard(path):
-       full_path = os.path.join(treetop, 'src', 'mainboard', path)
+def mainboardsetup(path):
+       global full_mainboard_path, mainboard_path
+       mainboard_path = os.path.join('mainboard', path)
+       loadoptions(mainboard_path, 'Options.lb', 'mainboardvariables')
+       full_mainboard_path = os.path.join(treetop, 'src', 'mainboard', path)
        vendor = re.sub("/.*", "", path)
         part_number = re.sub("[^/]*/", "", path)
-       setdefault('MAINBOARD', full_path, 1)
-       setdefault('MAINBOARD_VENDOR', vendor, 1)
-       setdefault('MAINBOARD_PART_NUMBER', part_number, 1)
-       dodir('/config', 'Config.lb')
-       part('mainboard', path, 'Config.lb', 0, 0)
+       setdefault('MAINBOARD', full_mainboard_path, 0)
+       setdefault('MAINBOARD_VENDOR', vendor, 0)
+       setdefault('MAINBOARD_PART_NUMBER', part_number, 0)
+
+def mainboard():
+       global curimage, dirstack, partstack
+       file = 'Config.lb'
+       partdir = mainboard_path
+       srcdir = os.path.join(treetop, 'src')
+       fulldir = os.path.join(srcdir, partdir)
+       type_name = flatten_name(partdir)
+       newpart = partobj(curimage, fulldir, partstack.tos(), 'mainboard', \
+               type_name, 0, 'chip')
+       #print "Configuring PART %s" % (type)
+       partstack.push(newpart)
+       #print "  new PART tos is now %s\n" %partstack.tos().info()
+       dirstack.push(fulldir)
+       loadoptions(mainboard_path, 'Options.lb', 'mainboardvariables')
+       # special case for 'cpu' parts.
+       # we could add a new function too, but this is rather trivial.
+       # if the part is a cpu, and we haven't seen it before,
+       # arrange to source the directory /cpu/'type'
+       doconfigfile(srcdir, partdir, file, 'cfgfile')
        curimage.setroot(partstack.tos())
        partpop()
 
@@ -1161,6 +1385,10 @@ def adddriver(driver_name):
        global curimage
        curimage.adddriverrule(driver_name)
 
+def addsmmobject(object_name):
+       global curimage
+       curimage.addsmmobjectrule(object_name)
+
 def target(name):
         global target_dir, target_name
        print "Configuring TARGET %s" % name
@@ -1180,16 +1408,27 @@ def cpudir(path):
        dodir(srcdir, "Config.lb")
        cpu_type = path
        
-def part(type, path, file, name, link):
+def devicepart(type):
        global curimage, dirstack, partstack
-       partdir = os.path.join(type, path)
+       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. 
+       dirstack.push(dirstack.tos())
+       
+def part(type, path, file, name):
+       global curimage, dirstack, partstack
+        partdir = os.path.join(type, path)
        srcdir = os.path.join(treetop, 'src')
        fulldir = os.path.join(srcdir, partdir)
-       type_name = flatten_name(os.path.join(type, path))
+       type_name = flatten_name(partdir)
        newpart = partobj(curimage, fulldir, partstack.tos(), type, \
-                       type_name, name, link)
-       print "Configuring PART %s, path %s" % (type, path)
+                       type_name, name, 'chip')
+       #print "Configuring PART %s, path %s" % (type, path)
        partstack.push(newpart)
+       #print "  new PART tos is now %s\n" %partstack.tos().info()
        dirstack.push(fulldir)
        # special case for 'cpu' parts. 
        # we could add a new function too, but this is rather trivial.
@@ -1205,13 +1444,14 @@ def partpop():
        curpart = partstack.tos()
        if (curpart == 0):
                fatal("Trying to pop non-existent part")
-       print "End PART %s" % curpart.part
+       #print "End PART %s" % curpart.part
        # Warn if options are used without being set in this part
        for op in curpart.uses_options.keys():
                if (not isset(op, curpart)):
                        notice("Option %s using default value %s" % (op, getformated(op, curpart.image)))
-       partstack.pop()
+       oldpart = partstack.pop()
        dirstack.pop()
+       #print "partstack.pop, TOS is now %s\n" % oldpart.info()
 
 def dodir(path, file):
        """dodir is like part but there is no new part"""
@@ -1253,9 +1493,10 @@ def adddep(id, str):
 def setarch(my_arch):
        """arch is 'different' ... darn it."""
        global curimage
+       print "SETTING ARCH %s\n" % my_arch
        curimage.setarch(my_arch)
        setdefault('ARCH', my_arch, 1)
-       part('arch', my_arch, 'Config.lb', 0, 0)
+       part('arch', my_arch, 'Config.lb', 0)
 
 def doconfigfile(path, confdir, file, rule):
        rname = os.path.join(confdir, file)
@@ -1333,9 +1574,12 @@ parser Config:
     token COMMENT:             'comment'
     token CONFIG:              'config'
     token CPU:                 'cpu'
+    token CPU_BUS:             'cpu_bus'
+    token CHIP:                        'chip'
     token DEFAULT:             'default'
     token DEFINE:              'define'
     token DEPENDS:             'depends'
+    token DEVICE:              'device'
     token DIR:                 'dir'
     token DRIVER:              'driver'
     token DRQ:                 'drq'
@@ -1368,6 +1612,7 @@ parser Config:
     token PRINT:               'print'
     token REGISTER:            'register'
     token ROMIMAGE:            'romimage'
+    token SMMOBJECT:           'smmobject'
     token SOUTHBRIDGE:         'southbridge'
     token SUPERIO:             'superio'
     token TARGET:              'target'
@@ -1382,6 +1627,7 @@ parser Config:
     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 DIRPATH:             r'[-a-zA-Z0-9_$()./]+'
     token ID:                  r'[a-zA-Z_.]+[a-zA-Z0-9_.]*'
     token DELEXPR:             r'{([^}]+|\\.)*}'
@@ -1392,7 +1638,11 @@ parser Config:
     token PCI:                 'pci'
     token PNP:                 'pnp'
     token I2C:                 'i2c'
-    token LINK:                 'link'
+    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 }}
@@ -1430,17 +1680,19 @@ parser Config:
     rule partid:       ID                      {{ return ID }}
                |       PATH                    {{ return PATH }}
 
-    rule parttype:     NORTHBRIDGE             {{ return 'northbridge' }} 
-               |       SUPERIO                 {{ return 'superio' }}
-               |       PMC                     {{ return 'pmc' }}
-               |       SOUTHBRIDGE             {{ return 'southbridge' }}
-               |       CPU                     {{ return 'cpu' }}
+#    rule parttype:    NORTHBRIDGE             {{ return 'northbridge' }} 
+#              |       SUPERIO                 {{ return 'superio' }}
+#              |       PMC                     {{ return 'pmc' }}
+#              |       SOUTHBRIDGE             {{ return 'southbridge' }}
+#              |       CPU                     {{ return 'cpu' }}
+#              |       CHIP                    {{ return '' }}
+#
+    rule parttype:     CHIP                    {{ return '' }}
 
-    rule partdef<<C>>:                         {{ name = 0 }} {{ link = 0 }}
-                       parttype partid
+    rule partdef<<C>>:                         {{ name = 0 }} 
+                       parttype partid         
                        [ STR                   {{ name = dequote(STR) }}
-                        ][ LINK NUM             {{ link = long(NUM, 10) }}
-                       ]                       {{ if (C): part(parttype, partid, 'Config.lb', name, link) }}
+                       ]                       {{ if (C): part(parttype, partid, 'Config.lb', name) }}
                        partend<<C>>            
 
     rule arch<<C>>:    ARCH ID                 {{ if (C): setarch(ID) }}
@@ -1461,6 +1713,10 @@ parser Config:
 
     rule driver<<C>>:  DRIVER DIRPATH          {{ if (C): adddriver(DIRPATH)}}
 
+    rule smmobject<<C>>:
+                       SMMOBJECT DIRPATH       {{ if (C): addsmmobject(DIRPATH)}}
+
+
     rule dir<<C>>:     DIR DIRPATH             {{ if (C): dodir(DIRPATH, 'Config.lb') }}
 
     rule default<<C>>: DEFAULT ID EQ value     {{ if (C): setdefault(ID, value, 0) }}
@@ -1472,13 +1728,10 @@ parser Config:
                        [ ELSE (stmt<<C and not c>>)* ]
                        END
 
-    rule depsacts<<ID, C>>:
-                       ( DEPENDS STR           {{ if (C): adddep(ID, STR) }}
-                       | ACTION STR            {{ if (C): addaction(ID, STR) }}
+    rule makerule<<C>>:        MAKERULE RULE           {{ if (C): addrule(RULE) }}
+                       ( DEPENDS STR           {{ if (C): adddep(RULE, STR) }}
+                       | ACTION STR            {{ if (C): addaction(RULE, STR) }}
                        )*
-
-    rule makerule<<C>>:        MAKERULE DIRPATH        {{ if (C): addrule(DIRPATH) }} 
-                       depsacts<<DIRPATH, C>> 
                        END
 
     rule makedefine<<C>>:
@@ -1493,16 +1746,16 @@ parser Config:
 
     rule register<<C>>:        REGISTER field '=' STR  {{ if (C): addregister(field, STR) }}
 
-    rule enable:                               {{ val = 1 }}
-                       [ ( ON                  {{ val = 1 }}
+    rule enable<<C>>:                          {{ val = 1 }}
+                       ( ON                    {{ val = 1 }}
                        | OFF                   {{ val = 0 }}
-                       ) ]                     {{ return val }}
+                       )                       {{ if(C): partstack.tos().set_enabled(val) }}
 
     rule resource<<C>>:                                {{ type = "" }}
-                       (  IO                   {{ type = "IORESOURCE_IO" }}
-                       |   MEM                 {{ type = "IORESOURCE_MEM" }}
-                       |   IRQ                 {{ type = "IORESOURCE_IRQ" }}
-                       |   DRQ                 {{ type = "IORESOURCE_DRQ" }}
+                       (  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 }}
@@ -1514,26 +1767,51 @@ parser Config:
                                                {{ if (C): partstack.tos().end_resources() }}
            
     
-    rule pci<<C>>:     PCI HEX_NUM             {{ bus = int(HEX_NUM,16) }}
-                       ':' HEX_NUM             {{ slot = int(HEX_NUM,16) }}
-                       '.' HEX_NUM             {{ function = int(HEX_NUM, 16) }}
-                       enable 
-                                               {{ if (C): partstack.tos().addpcipath(enable, bus, slot, function) }}
-                       resources<<C>>
+    rule pci<<C>>:     PCI                     {{ if (C): devicepart('pci') }}
 
-    rule pnp<<C>>:     PNP HEX_NUM             {{ port = int(HEX_NUM,16) }}
+                       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) }}
-                       enable
-                                               {{ if (C): partstack.tos().addpnppath(enable, port, device) }}
-                       resources<<C>>
-
-
-    rule i2c<<C>>:     I2C HEX_NUM             {{ device = int(HEX_NUM, 16) }}
-                       enable
-                                               {{ if (C): partstatck.tos().addi2cpath(enable, device) }}
-                       resources<<C>>
-                       
-                       
+                                               {{ 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 }}
 
@@ -1547,6 +1825,11 @@ parser Config:
 
     rule config<<C>>:  CONFIG PATH             {{ if (C): addconfig(PATH) }}
 
+    rule device<<C>>:   DEVICE dev_path<<C>>
+                       enable<<C>>                     
+                       resources<<C>>
+                       partend<<C>> 
+
     rule stmt<<C>>:    arch<<C>>               {{ return arch}}
                |       addaction<<C>>          {{ return addaction }}
                |       config<<C>>             {{ return config}}
@@ -1566,18 +1849,27 @@ parser Config:
                |       partdef<<C>>            {{ return partdef }}
                |       prtstmt<<C>>            {{ return prtstmt }}
                |       register<<C>>           {{ return register }}
-               |       pci<<C>>                {{ return pci }}
-               |       pnp<<C>>                {{ return pnp }}
+               |       device<<C>>             {{ return device }}
+               |       smmobject<<C>>          {{ return smmobject }}
 
     # ENTRY for parsing Config.lb file
     rule cfgfile:      (uses<<1>>)* 
                        (stmt<<1>>)*
                        EOF                     {{ return 1 }}
 
+    rule cfgfile:      (uses<<1>>)* 
+                       (stmt<<1>>)*
+                       EOF                     {{ return 1 }}
+
     rule usesid<<C>>:  ID                      {{ if (C): usesoption(ID) }}
 
     rule uses<<C>>:    USES (usesid<<C>>)+
 
+    rule mainboardvariables:   (uses<<1>>)*
+                               (default<<1>>)*
+                               (option<<1>>)*
+                               END             {{ return 1}}
+
     rule value:                STR                     {{ return dequote(STR) }} 
                |       expr                    {{ return expr }}
                |       DELEXPR                 {{ return DELEXPR }}
@@ -1595,8 +1887,8 @@ parser Config:
 
     rule payload<<C>>: PAYLOAD DIRPATH         {{ if (C): payload(DIRPATH) }}
 
-    rule mainboard<<C>>:
-                       MAINBOARD PATH          {{ if (C): mainboard(PATH) }}
+    rule mainboard:
+                       MAINBOARD PATH          {{ mainboardsetup(PATH) }}
 
     rule romif<<C>>:   IF ID                   {{ c = lookup(ID) }}
                        (romstmt<<C and c>>)* 
@@ -1605,7 +1897,6 @@ parser Config:
 
     rule romstmt<<C>>: romif<<C>>
                |       option<<C>>
-               |       mainboard<<C>>
                |       payload<<C>>
 
     rule romimage:     ROMIMAGE STR            {{ startromimage(dequote(STR)) }}
@@ -1623,9 +1914,9 @@ parser Config:
                |       opstmt<<1>>
 
     # ENTRY for parsing root part
-    rule board:                LOADOPTIONS             {{ loadoptions() }}
+    rule board:                {{ loadoptions("config", "Options.lb", "options") }}
                        TARGET DIRPATH          {{ target(DIRPATH) }}
-                       (uses<<1>>)*
+                       mainboard
                        (romstmts)*             
                        EOF                     {{ return 1 }}
 
@@ -1660,9 +1951,13 @@ parser Config:
 #              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]))
+       file.write("# File: %s is autogenerated\n" % fname)
+
+def writemakefilefooter(file, fname):
+       file.write("\n\n%s: %s %s\n"
+               % (os.path.basename(fname), os.path.abspath(sys.argv[0]), top_config_file))
+       file.write("\t(cd %s ; export PYTHONPATH=%s/util/newconfig ; python %s %s %s)\n\n"
+               % (os.getcwd(), treetop, sys.argv[0], sys.argv[1], sys.argv[2]))
 
 def writemakefilesettings(path):
        """ Write Makefile.settings to seperate the settings
@@ -1676,6 +1971,7 @@ def writemakefilesettings(path):
        writemakefileheader(file, filename)
        file.write("TOP:=%s\n" % (treetop))
        file.write("TARGET_DIR:=%s\n" % target_dir)
+       writemakefilefooter(file, filename)
        file.close()
 
 def writeimagesettings(image):
@@ -1708,6 +2004,7 @@ def writeimagesettings(image):
        for o in exported:
                file.write("export VARIABLES += %s\n" % o.name)
        file.write("\n")
+       writemakefilefooter(file,filename)
        file.close()
 
 # write the romimage makefile
@@ -1720,6 +2017,9 @@ def writeimagemakefile(image):
        file = safe_open(makefilepath, 'w+')
        writemakefileheader(file, makefilepath)
 
+       # main rule
+       file.write("\nall: coreboot.rom\n\n")
+       file.write(".PHONY: all\n\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.
@@ -1735,8 +2035,6 @@ def writeimagemakefile(image):
                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")
@@ -1755,6 +2053,13 @@ def writeimagemakefile(image):
                file.write("OBJECTS += %s\n" % (obj_name))
                file.write("SOURCES += %s\n" % (obj_source))
 
+       for srule, smm in image.getsmmobjectrules().items():
+               s_name = smm[0]
+               s_source = smm[1]
+               file.write("SMM-OBJECTS += %s\n" % (s_name))
+               file.write("SOURCES += %s\n" % (s_source))
+
+
        # for chip_target.c
        file.write("OBJECTS += static.o\n")
        file.write("SOURCES += static.c\n")
@@ -1797,11 +2102,9 @@ def writeimagemakefile(image):
                if (type  == 'S'):
                        # for .S, .o depends on .s
                        file.write("%s: %s.s\n" % (init[0], init[3]))
-                       file.write("\t@echo $(CC) ... -o $@ $<\n")
                        file.write("\t$(CC) -c $(CPU_OPT) -o $@ $<\n")
                        # and .s depends on .S
                        file.write("%s.s: %s\n" % (init[3], source))
-                       file.write("\t@echo $(CPP) ... $< > $@\n")
                        # Note: next 2 lines are ONE output line!
                        file.write("\t$(CPP) $(CPPFLAGS) $< ")
                        file.write(">$@.new && mv $@.new $@\n")
@@ -1816,11 +2119,9 @@ def writeimagemakefile(image):
                if (type  == 'S'):
                        # for .S, .o depends on .s
                        file.write("%s: %s.s\n" % (obj[0], obj[3]))
-                       file.write("\t@echo $(CC) ... -o $@ $<\n")
                        file.write("\t$(CC) -c $(CPU_OPT) -o $@ $<\n")
                        # and .s depends on .S
                        file.write("%s.s: %s\n" % (obj[3], source))
-                       file.write("\t@echo $(CPP) ... $< > $@\n")
                        # Note: next 2 lines are ONE output line!
                        file.write("\t$(CPP) $(CPPFLAGS) $< ")
                        file.write(">$@.new && mv $@.new $@\n")
@@ -1835,6 +2136,23 @@ def writeimagemakefile(image):
                file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
                #file.write("%s\n" % objrule[2])
 
+       file.write("\n# smmobjectrules:\n")
+       for irule, smm in image.getsmmobjectrules().items():
+               source = topify(smm[1])
+               type = smm[2]
+               if (type  == 'S'):
+                       # for .S, .o depends on .s
+                       file.write("%s: %s.s\n" % (smm[0], smm[3]))
+                       file.write("\t$(CC) -c $(CPU_OPT) -o $@ $<\n")
+                       # and .s depends on .S
+                       file.write("%s.s: %s\n" % (smm[3], source))
+                       # Note: next 2 lines are ONE output line!
+                       file.write("\t$(CPP) $(CPPFLAGS) $< ")
+                       file.write(">$@.new && mv $@.new $@\n")
+               else:
+                       file.write("%s: %s\n" % (smm[0], source))
+                       file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
+
        # special rule for chip_target.c
        file.write("static.o: static.c\n")
        file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
@@ -1847,7 +2165,7 @@ def writeimagemakefile(image):
        for genfile in ['Makefile',
                        'nsuperio.c',
                        'static.c',
-                       'LinuxBIOSDoc.config' ]:
+                       'corebootDoc.config' ]:
                file.write("GENERATED += %s\n" % genfile)
        file.write("GENERATED += %s\n" % image.getincludefilename())
 
@@ -1864,6 +2182,7 @@ def writeimagemakefile(image):
                file.write("\n")
                for i in m.actions:
                        file.write("\t%s\n" % i)
+       writemakefilefooter(file, makefilepath)
        file.close()
 
 #
@@ -1872,34 +2191,48 @@ def writemakefile(path):
        print "Creating", makefilepath
        file = safe_open(makefilepath, 'w+')
        writemakefileheader(file, makefilepath)
-       file.write("include Makefile.settings\n\n")
 
        # main rule
-       file.write("all: ")
-       for i in romimages.keys():
-               file.write("%s-rom " % i)
-       file.write("buildroms\n\n")
+       file.write("\nall:")
+       for i in buildroms:
+               file.write(" %s" % i.name)
+       file.write("\n\n")      
+       file.write("include Makefile.settings\n\n")
        for i, o in romimages.items():
-               file.write("%s-rom:\n" % o.getname())
+               file.write("%s/coreboot.rom:\n" % o.getname())
                file.write("\tif (cd %s; \\\n" % o.getname())
-               file.write("\t\tmake linuxbios.rom)\\\n")
+               file.write("\t\t$(MAKE) coreboot.rom)\\\n")
                file.write("\tthen true; else exit 1; fi;\n\n")
        file.write("clean: ")
        for i in romimages.keys():
-               file.write("%s-clean " % i)
+               file.write(" %s-clean" % i)
+       file.write(" base-clean")
        file.write("\n\n")
        for i, o in romimages.items():
                file.write("%s-clean:\n" % o.getname())
-               file.write("\t(cd %s; make clean)\n" % o.getname())
-       
-       file.write("\nbuildroms:\n")
+               file.write("\t(cd %s; $(MAKE) clean)\n\n" % o.getname())
+       file.write("base-clean:\n")
+       file.write("\trm -f romcc*\n\n")
+
        for i in buildroms:
-               file.write("\tcat ")
+               file.write("%s:" % i.name)
                for j in i.roms:
-                       file.write("%s/linuxbios.rom " % j )
-               file.write("> %s\n" % i.name)
-       file.write("\n")
-       
+                       file.write(" %s/coreboot.rom " % j)
+               file.write("\n")
+               file.write("\t cat ")
+               for j in i.roms:
+                       file.write(" %s/coreboot.rom " % j)
+               file.write("> %s\n\n" %i.name)
+
+
+       file.write(".PHONY: all clean")
+       for i in romimages.keys():
+               file.write(" %s-clean" % i)
+       for i, o in romimages.items():
+               file.write(" %s/coreboot.rom" % o.getname())
+       file.write("\n\n")
+
+       writemakefilefooter(file, makefilepath)
        file.close()
 
 def writeinitincludes(image):
@@ -1947,22 +2280,27 @@ def dumptree(part, lvl):
        # dump the siblings -- actually are there any? not sure
        # siblings are:
        debug.info(debug.dumptree, "DUMPTREE SIBLINGS are")
-       kid = part.siblings
+       kid = part.next_sibling
        while (kid):
                kid.dumpme(lvl)
-               kid = kid.siblings
+               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 "Creating", filename
        file = safe_open(filename, 'w+')
-       file.write("#include <device/chip.h>\n")
+       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)
@@ -1975,19 +2313,19 @@ def gencode(part, file, pass_num):
        part.gencode(file, pass_num)
        # dump the siblings -- actually are there any? not sure
        debug.info(debug.gencode, "GENCODE SIBLINGS are")
-       kid = part.siblings
+       kid = part.next_sibling
        while (kid):
                kid.gencode(file, pass_num)
-               kid = kid.siblings
+               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.siblings
+       kid = part.next_sibling
        while (kid):
                if (kid.children):
                        gencode(kid.children, file, pass_num)
-               kid = kid.siblings
+               kid = kid.next_sibling
        debug.info(debug.gencode, "DONE GENCODE")
 
 def verifyparse():
@@ -2000,12 +2338,11 @@ def verifyparse():
                        fatal("An init file must be specified")
                for op in image.exported_options:
                        if (getoptionvalue(op.name, op, image) == 0 and getoptionvalue(op.name, op, 0) == 0):
-                               error("Exported option %s has no value (check Options.lb)" % op.name)
+                               warning("Exported option %s has no value (check Options.lb)" % op.name);
        print("Verifing global options")
        for op in global_exported_options:
                if (getoptionvalue(op.name, op, 0) == 0):
-                       error("Exported option %s has no value (check Options.lb)" % op.name)
-       exitiferrors()
+                       notice("Exported option %s has no value (check Options.lb)" % op.name);
                        
 #=============================================================================
 #              MAIN PROGRAM
@@ -2013,7 +2350,7 @@ def verifyparse():
 if __name__=='__main__':
        from sys import argv
        if (len(argv) < 3):
-               fatal("Args: <file> <path to linuxbios>")
+               fatal("Args: <file> <path to coreboot>")
 
        top_config_file = os.path.abspath(sys.argv[1])