This patch unifies the use of config options in v2 to all start with CONFIG_
[coreboot.git] / util / newconfig / config.g
index ef663577f49ddf60d3cbb55c9385fe8e66fe8a3c..81ce4290219f77ab76c791a3a5f2d2804bf75497 100644 (file)
@@ -22,7 +22,10 @@ global_uses_options = {}
 global_exported_options = []
 romimages = {}
 buildroms = []
+pciroms = []
+rommapping = {}
 curimage = 0
+bootblocksize = 0
 alloptions = 0 # override uses at top level
 
 local_path = re.compile(r'^\.')
@@ -93,6 +96,7 @@ class debug_info:
        dict = 4
        statement = 5
        dump = 6
+       gengraph = 7
 
        def __init__(self, *level):
                self.__level = level
@@ -108,7 +112,8 @@ class debug_info:
                        print str
 
 global debug
-debug = debug_info(debug_info.none)
+debug = debug_info(debug_info.dumptree)
+debug = debug_info(debug_info.object)
 
 # -----------------------------------------------------------------------------
 #                    Error Handling
@@ -182,7 +187,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"""
@@ -200,7 +205,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
@@ -223,9 +228,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 = []
 
@@ -272,8 +280,11 @@ class romimage:
                self.arch = arch
 
        def setpayload(self, payload):
+               global rommapping
                self.payload = payload
 
+               rommapping[self.name] = payload
+
        def setinitfile(self, initfile):
                self.initfile = initfile
 
@@ -312,6 +323,22 @@ class romimage:
                        return
                fatal("No such rule \"%s\" for addmakedepend" % id)
 
+       def addmakeobject(self, file, obj):
+               source = topify(obj[1])
+               type = obj[2]
+               if (type  == 'S'):
+                       # for .S, .o depends on .s
+                       file.write("%s: %s.s\n" % (obj[0], obj[3]))
+                       file.write("\t$(CC) -c $(CONFIG_CPU_OPT) -o $@ $<\n")
+                       # and .s depends on .S
+                       file.write("%s.s: %s\n" % (obj[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" % (obj[0], source))
+                       file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
+
        # this is called with an an object name. 
        # the easiest thing to do is add this object to the current 
        # component.
@@ -326,14 +353,20 @@ class romimage:
                type = object_name[-1:]
                if (object_name[0] == '.'):
                        source = base + suffix
+                       object = base + '.o'
+                       rel_base = base
                else:
-                       source = os.path.join(dirstack.tos(), base + suffix)
-               object = base + '.o'
-               debug.info(debug.object, "add object %s source %s" % (object_name, source))
-               l = getdict(dict, base)
+                       rel_base = re.sub(treetop, "", os.path.join(dirstack.tos(), base))
+                       source = "$(TOP)/" + rel_base + suffix
+                       if (rel_base[0] == '/'):
+                               rel_base = re.sub("^/", "", rel_base)
+                       object = rel_base + '.o'
+
+               debug.info(debug.object, "add object %s source %s" % (object, source))
+               l = getdict(dict, rel_base)
                if (l):
-                       warning("object/driver %s previously defined" % base)
-               setdict(dict, base, [object, source, type, base])
+                       warning("object/driver %s previously defined" % rel_base)
+               setdict(dict, rel_base, [object, source, type, rel_base])
 
        def addinitobjectrule(self, name):
                self.addobjectdriver(self.initobjectrules, name)
@@ -344,6 +377,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
 
@@ -371,6 +407,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)
 
@@ -452,6 +497,13 @@ class buildrom:
        def __getitem__(self,i):
                return self.roms[i]
 
+class pci_rom:
+       """A pci_rom statement"""
+       def __init__ (self, filename, vendor, device):
+               self.name = filename
+               self.pci_vid = vendor
+               self.pci_did = device
+       
 class initinclude:
        """include file for initialization code"""
        def __init__ (self, str, path):
@@ -572,8 +624,12 @@ class option_value:
 class partobj:
        """A configuration part"""
        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))
+               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
@@ -682,6 +738,18 @@ class partobj:
                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"""
@@ -916,40 +984,53 @@ class partobj:
                if ((slot < 0) or (slot > 0x1f)):
                        fatal("Invalid device id")
                if ((function < 0) or (function > 7)):
-                       fatal("Invalid function")
-               self.set_path(".type=DEVICE_PATH_PCI,.u={.pci={ .devfn = PCI_DEVFN(0x%x,%d)}}" % (slot, function))
+                       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 > 0xff)):
+               if ((device < 0) or (device > 0xffff)):
                        fatal("Invalid device")
-               self.set_path(".type=DEVICE_PATH_PNP,.u={.pnp={ .port = 0x%x, .device = 0x%x }}" % (port, 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,.u={.i2c={ .device = 0x%x }}" % (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,.u={.apic={ .apic_id = 0x%x }}" % (apic_id))
+               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,.u={.pci_domain={ .domain = 0x%x }}" % (pci_domain))
+               self.set_path(".type=DEVICE_PATH_PCI_DOMAIN,{.pci_domain={ .domain = 0x%x }}" % (pci_domain))
     
        def addapic_clusterpath(self, cluster):
-               """ Add a pci_domain number to a chip """
+               """ 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))
+               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))
     
        def usesoption(self, name):
                """Declare option that can be used by this part"""
@@ -977,6 +1058,8 @@ def getdict(dict, name):
 
 def setdict(dict, name, value):
        debug.info(debug.dict, "setdict sets %s to %s" % (name, value))
+       if name in dict.keys():
+               print "Duplicate in dict: %s" % name
        dict[name] = value
 
 # options. 
@@ -1011,7 +1094,8 @@ def getoptionvalue(name, op, image):
        global global_option_values
        #print "getoptionvalue name %s op %s image %s\n" % (name, op,image)
        if (op == 0):
-               print_stack()
+               # 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)
@@ -1033,7 +1117,7 @@ def getoption(name, image):
        elif (curpart):
                o = getdict(curpart.uses_options, name)
                if (o == 0):
-                       print "curpart.uses_optins is %s\n" % curpart.uses_options
+                       print "curpart.uses_options is %s\n" % curpart.uses_options
        else:
                o = getdict(global_uses_options, name)
        v = getoptionvalue(name, o, image)
@@ -1300,7 +1384,10 @@ def startromimage(name):
 
 def endromimage():
        global curimage
+       global bootblocksize
        mainboard()
+       imagesize = getoption("CONFIG_ROM_IMAGE_SIZE", curimage)
+       bootblocksize += imagesize
        print "End ROMIMAGE"
        curimage = 0
        #curpart = 0
@@ -1312,9 +1399,9 @@ def mainboardsetup(path):
        full_mainboard_path = os.path.join(treetop, 'src', 'mainboard', path)
        vendor = re.sub("/.*", "", path)
         part_number = re.sub("[^/]*/", "", path)
-       setdefault('MAINBOARD', full_mainboard_path, 0)
-       setdefault('MAINBOARD_VENDOR', vendor, 0)
-       setdefault('MAINBOARD_PART_NUMBER', part_number, 0)
+       setdefault('CONFIG_MAINBOARD', full_mainboard_path, 0)
+       setdefault('CONFIG_MAINBOARD_VENDOR', vendor, 0)
+       setdefault('CONFIG_MAINBOARD_PART_NUMBER', part_number, 0)
 
 def mainboard():
        global curimage, dirstack, partstack
@@ -1324,7 +1411,7 @@ def mainboard():
        fulldir = os.path.join(srcdir, partdir)
        type_name = flatten_name(partdir)
        newpart = partobj(curimage, fulldir, partstack.tos(), 'mainboard', \
-               type_name, 0, 'chip')
+               'mainboard', 0, 'chip')
        #print "Configuring PART %s" % (type)
        partstack.push(newpart)
        #print "  new PART tos is now %s\n" %partstack.tos().info()
@@ -1344,6 +1431,12 @@ def addbuildrom(filename, size, roms):
        b = buildrom(filename, size, roms)
        buildroms.append(b)
 
+def addpci_rom(filename, vendor, device):
+       global pciroms
+       print "Add PCI ROM %s" %filename
+       p = pci_rom(filename, vendor, device)
+       pciroms.append(p)
+
 def addinitobject(object_name):
        global curimage
        curimage.addinitobjectrule(object_name)
@@ -1356,6 +1449,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
@@ -1437,6 +1534,20 @@ def dodir(path, file):
        doconfigfile(fullpath, path, file, 'cfgfile')
        dirstack.pop()
 
+def dofile(path):
+       """dofile is a simple include for single files"""
+       # if the first char is '/', it is relative to treetop, 
+       # else relative to curdir
+       # os.path.join screws up if the name starts with '/', sigh.
+       if (path[0] == '/'):
+               fullpath = os.path.join(treetop, 'src')
+               path = re.sub('^/*', '', path)
+       else:
+               fullpath = dirstack.tos()
+       print "INCLUDE %s" %path
+       debug.info(debug.statement, "DOFILE: path %s, fullpath %s" % (path, fullpath))
+       doconfigfile(fullpath, '', path, 'cfgfile')
+
 def lookup(name):
        global curimage
        return getoption(name, curimage)
@@ -1460,9 +1571,9 @@ def adddep(id, str):
 def setarch(my_arch):
        """arch is 'different' ... darn it."""
        global curimage
-       print "SETTING ARCH %s\n" % my_arch
+       print "SETTING CONFIG_ARCH %s\n" % my_arch
        curimage.setarch(my_arch)
-       setdefault('ARCH', my_arch, 1)
+       setdefault('CONFIG_ARCH', my_arch, 1)
        part('arch', my_arch, 'Config.lb', 0)
 
 def doconfigfile(path, confdir, file, rule):
@@ -1536,16 +1647,18 @@ parser Config:
     token ACTION:              'action'
     token ADDACTION:           'addaction'
     token ALWAYS:              'always'
-    token ARCH:                        'arch'
+    token CONFIG_ARCH:                 'arch'
     token BUILDROM:            'buildrom'
     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 DEVICE_ID:           'device_id'
     token DIR:                 'dir'
     token DRIVER:              'driver'
     token DRQ:                 'drq'
@@ -1559,11 +1672,12 @@ parser Config:
     token INIT:                        'init'
     token INITOBJECT:          'initobject'
     token INITINCLUDE:         'initinclude'
+    token INCLUDE:             'include'
     token IO:                  'io'
     token IRQ:                 'irq'
     token LDSCRIPT:            'ldscript'
     token LOADOPTIONS:         'loadoptions'
-    token MAINBOARD:           'mainboard'
+    token CONFIG_MAINBOARD:            'mainboard'
     token MAINBOARDINIT:       'mainboardinit'
     token MAKEDEFINE:          'makedefine'
     token MAKERULE:            'makerule'
@@ -1574,15 +1688,18 @@ parser Config:
     token OBJECT:              'object'
     token OPTION:              'option'
     token PAYLOAD:             'payload'
+    token PCI_ROM:             'pci_rom'
     token PMC:                 'pmc'
     token PRINT:               'print'
     token REGISTER:            'register'
     token ROMIMAGE:            'romimage'
+    token SMMOBJECT:           'smmobject'
     token SOUTHBRIDGE:         'southbridge'
     token SUPERIO:             'superio'
     token TARGET:              'target'
     token USED:                        'used'
     token USES:                        'uses'
+    token VENDOR_ID:           'vendor_id'
     token WRITE:               'write'
     token NUM:                 '[0-9]+'
     token HEX_NUM:             '[0-9a-fA-F]+'
@@ -1592,7 +1709,8 @@ 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 DIRPATH:             r'[-a-zA-Z0-9_$()./]+'
+    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'{([^}]+|\\.)*}'
     token STR:                 r'"([^\\"]+|\\.)*"'
@@ -1604,12 +1722,14 @@ parser Config:
     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 }}
+                       | "[|][|]" logical      {{ l = l or logical }}
                        )*                      {{ return l }}
 
     rule logical:      factor                  {{ n = factor }}
@@ -1657,7 +1777,7 @@ parser Config:
                        ]                       {{ if (C): part(parttype, partid, 'Config.lb', name) }}
                        partend<<C>>            
 
-    rule arch<<C>>:    ARCH ID                 {{ if (C): setarch(ID) }}
+    rule arch<<C>>:    CONFIG_ARCH ID                  {{ if (C): setarch(ID) }}
                        partend<<C>>
     
     rule mainboardinit<<C>>:
@@ -1675,6 +1795,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) }}
@@ -1686,13 +1810,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>>:
@@ -1755,13 +1876,25 @@ parser Config:
                        HEX_NUM                 {{ cluster = int(HEX_NUM, 16) }}
                                                {{ if (C): partstack.tos().addapic_clusterpath(cluster) }}
 
-    rule dev_path<<C>>:                                
+    rule include<<C>>: INCLUDE DIRPATH         {{ dofile(DIRPATH) }}
+
+    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 }}
@@ -1790,6 +1923,7 @@ parser Config:
                |       iif<<C>>                {{ return iif }}
                |       init<<C>>               {{ return init }}
                |       initinclude<<C>>        {{ return initinclude }}
+               |       include<<C>>            {{ return include }}
                |       initobject<<C>>         {{ return initobject }}
                |       ldscript<<C>>           {{ return ldscript}}
                |       mainboardinit<<C>>      {{ return mainboardinit }}
@@ -1801,16 +1935,13 @@ parser Config:
                |       prtstmt<<C>>            {{ return prtstmt }}
                |       register<<C>>           {{ return register }}
                |       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>>)+
@@ -1838,7 +1969,7 @@ parser Config:
     rule payload<<C>>: PAYLOAD DIRPATH         {{ if (C): payload(DIRPATH) }}
 
     rule mainboard:
-                       MAINBOARD PATH          {{ mainboardsetup(PATH) }}
+                       CONFIG_MAINBOARD PATH           {{ mainboardsetup(PATH) }}
 
     rule romif<<C>>:   IF ID                   {{ c = lookup(ID) }}
                        (romstmt<<C and c>>)* 
@@ -1859,9 +1990,17 @@ parser Config:
 
     rule buildrom:     BUILDROM DIRPATH expr roms      {{ addbuildrom(DIRPATH, expr, roms) }}
 
+    rule pci_vid:      VENDOR_ID EQ term       {{ return term }}
+
+    rule pci_did:      DEVICE_ID EQ term       {{ return term }}
+
+
+    rule pci_rom:      PCI_ROM DIRPATH pci_vid pci_did {{ addpci_rom(DIRPATH, pci_vid, pci_did) }}
+
     rule romstmts:     romimage 
                |       buildrom
                |       opstmt<<1>>
+               |       pci_rom
 
     # ENTRY for parsing root part
     rule board:                {{ loadoptions("config", "Options.lb", "options") }}
@@ -1901,9 +2040,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
@@ -1917,6 +2060,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):
@@ -1949,6 +2093,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
@@ -1961,6 +2106,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.
@@ -1968,16 +2116,14 @@ def writeimagemakefile(image):
        file.write("# Get the value of TOP, VARIABLES, and several other variables.\n")
        file.write("include Makefile.settings\n\n")
        file.write("# Function to create an item like -Di586 or -DCONFIG_MAX_CPUS='1' or -Ui686\n")
-       file.write("D_item = $(if $(subst undefined,,$(origin $1)),-D$1$(if $($1),='$($1)',),-U$1)\n\n")
+       file.write("D_item = $(shell echo '$(if $(subst undefined,,$(origin $1)),\\#define $1$(if $($1), $($1),),\\#undef $1)' >> settings.h)\n\n")
        file.write("# Compute the value of CPUFLAGS here during make's first pass.\n")
-       file.write("CPUFLAGS := $(foreach _var_,$(VARIABLES),$(call D_item,$(_var_)))\n\n")
+       file.write("CPUFLAGS := $(strip $(shell echo '/* autogenerated */' > settings.h)$(foreach _var_,$(VARIABLES),$(call D_item,$(_var_)))-include $(CURDIR)/settings.h)\n\n")
 
        for i in image.getuserdefines():
                file.write("%s\n" %i)
        file.write("\n")
 
-       # main rule
-       file.write("all: linuxbios.rom")
        # print out all the object dependencies
        file.write("\n# object dependencies (objectrules:)\n")
        file.write("INIT-OBJECTS :=\n")
@@ -1996,6 +2142,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")
@@ -2033,42 +2186,15 @@ def writeimagemakefile(image):
 
        file.write("\n# initobjectrules:\n")
        for irule, init in image.getinitobjectrules().items():
-               source = topify(init[1])
-               type = init[2]
-               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")
-               else:
-                       file.write("%s: %s\n" % (init[0], source))
-                       file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
+               image.addmakeobject(file, init);
 
-       file.write("\n# objectrules:\n")
+       file.write("\n# objectrules (don't duplicate initobjects):\n")
        for objrule, obj in image.getobjectrules().items():
-               source = topify(obj[1])
-               type = obj[2]
-               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")
+
+               if (getdict(image.getinitobjectrules(), obj[3])):
+                       debug.info(debug.object, "skipping %s" % (obj[3]))
                else:
-                       file.write("%s: %s\n" % (obj[0], source))
-                       file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
-               #file.write("%s\n" % objrule[2])
+                       image.addmakeobject(file, obj);
 
        for driverrule, driver in image.getdriverrules().items():
                source = topify(driver[1])
@@ -2076,6 +2202,10 @@ 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():
+               image.addmakeobject(file, smm);
+
        # special rule for chip_target.c
        file.write("static.o: static.c\n")
        file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
@@ -2088,7 +2218,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())
 
@@ -2105,42 +2235,102 @@ def writeimagemakefile(image):
                file.write("\n")
                for i in m.actions:
                        file.write("\t%s\n" % i)
+       writemakefilefooter(file, makefilepath)
        file.close()
 
 #
 def writemakefile(path):
+       global rommapping
+       global bootblocksize
        makefilepath = os.path.join(path, "Makefile")
        print "Creating", makefilepath
        file = safe_open(makefilepath, 'w+')
        writemakefileheader(file, makefilepath)
-       file.write("include Makefile.settings\n\n")
+
+       # Hack to get the necessary settings (CONFIG_CBFS):
+       file.write("include %s/Makefile.settings\n\n" % romimages.keys()[0])
 
        # 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")
+
+       # cbfstool rules
+       file.write("\ncbfstool:\n\tmkdir -p cbfs/tools/lzma\n\t$(MAKE) -C $(TOP)/util/cbfstool obj=$(shell pwd)/cbfs\n")
+       file.write("\ncbfstool-clean:\n\t$(MAKE) -C $(TOP)/util/cbfstool obj=$(shell pwd)/cbfs clean\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")
+
+       file.write("ifeq \"$(CONFIG_CBFS)\" \"1\"\n\n")
+       file.write("CBFS_COMPRESS_FLAG:=\n")
+       file.write("ifeq \"$(CONFIG_COMPRESSED_PAYLOAD_LZMA)\" \"1\"\nCBFS_COMPRESS_FLAG:=l\nendif\n\n")
+
        for i in buildroms:
-               file.write("\tcat ")
+               file.write("%s: cbfstool" %(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")
+
+               romsize = getoption("CONFIG_ROM_SIZE", image)
+
+               file.write("\n\trm -f %s\n" %(i.name))
+
+               # build the bootblock here.
+               file.write("\n\tcat")
+               for j in i.roms:
+                       file.write(" %s/coreboot.rom " % j)
+               file.write("> %s.bootblock\n\n" %i.name)
+               file.write("\t./cbfs/cbfstool %s create %s %s %s.bootblock\n"
+                          %(i.name, romsize, bootblocksize, i.name))
+               for j in pciroms:
+                       file.write("\t./cbfs/cbfstool %s add %s pci%04x,%04x.rom optionrom\n" % (i.name, j.name, j.pci_vid, j.pci_did))
+               for j in i.roms:
+                       #failover is a hack that will go away soon. 
+                       if (j != "failover") and (rommapping[j] != "/dev/null"):
+                               file.write("\t./cbfs/cbfstool %s add-payload %s %s/payload $(CBFS_COMPRESS_FLAG)\n" % (i.name, rommapping[j], j,))
+                       if (j != "failover"):
+                               file.write("\t./cbfs/cbfstool %s add-stage %s/coreboot_ram %s/coreboot_ram $(CBFS_COMPRESS_FLAG)\n" % (i.name, j, j,))
+                       file.write("\tif [ -f %s/coreboot_apc ]; then ./cbfs/cbfstool %s add-stage %s/coreboot_apc %s/coreboot_apc $(CBFS_COMPRESS_FLAG); fi\n" % (j, i.name, j, j,))
+               file.write("\t./cbfs/cbfstool %s print\n" % i.name)
+               file.write("\n")
+       file.write("else\n\n")
+
+       for i in buildroms:
+               file.write("%s:" % i.name)
+               for j in i.roms:
+                       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("endif\n\n")
+
+       file.write(".PHONY: all clean cbfstool")
+       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):
@@ -2212,7 +2402,9 @@ def writecode(image):
        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()
 
@@ -2236,6 +2428,75 @@ def gencode(part, 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 "Creating", filename
+       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)
+
 def verifyparse():
        """Add any run-time checks to verify that parsing the configuration
        was successful"""
@@ -2258,7 +2519,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])
 
@@ -2286,6 +2547,30 @@ if __name__=='__main__':
                        print "Creating directory %s" % img_dir
                        os.makedirs(img_dir)
 
+               for objrule, obj in image.getobjectrules().items():
+                       sub_dir = img_dir + '/' + os.path.dirname(obj[0])
+                       if not os.path.isdir(sub_dir):
+                               print "Creating sub directory %s" % sub_dir
+                               os.makedirs(sub_dir)
+
+               for driverrule, driver in image.getdriverrules().items():
+                       sub_dir = img_dir + '/' + os.path.dirname(driver[0])
+                       if not os.path.isdir(sub_dir):
+                               print "Creating sub directory %s" % sub_dir
+                               os.makedirs(sub_dir)
+
+               for srule, smm in image.getsmmobjectrules().items():
+                       sub_dir = img_dir + '/' + os.path.dirname(smm[0])
+                       if not os.path.isdir(sub_dir):
+                               print "Creating sub directory %s" % sub_dir
+                               os.makedirs(sub_dir)
+
+               for irule, init in image.getinitobjectrules().items():
+                       sub_dir = img_dir + '/' + os.path.dirname(init[0])
+                       if not os.path.isdir(sub_dir):
+                               print "Creating sub directory %s" % sub_dir
+                               os.makedirs(sub_dir)
+
                if (debug.level(debug.dump)):
                        for i in image.getinitincludes():
                                debug.info(debug.dump, "crt0include file %s" % i)
@@ -2301,6 +2586,7 @@ if __name__=='__main__':
                writeinitincludes(image)
                writeimagemakefile(image)
                writeldoptions(image)
+               writegraph(image)
 
        writemakefilesettings(target_dir)
        writemakefile(target_dir)