16 full_mainboard_path = ''
19 global_options_by_order = []
20 global_option_values = {}
21 global_uses_options = {}
22 global_exported_options = []
26 alloptions = 0 # override uses at top level
28 local_path = re.compile(r'^\.')
29 include_pattern = re.compile(r'%%([^%]+)%%')
31 # the cpu type for this mainboard
34 # -----------------------------------------------------------------------------
36 # -----------------------------------------------------------------------------
39 """Used to keep track of the current part or dir"""
41 def __init__ (self, stack):
50 if (self.index < self.len):
51 s = self.stack[self.index]
52 self.index = self.index + 1
60 return len(self.stack)
62 def __getitem__ (self, i):
66 return self.__stack_iter(self.stack)
69 self.stack.append(part)
73 return self.stack.pop()
84 return (len(self.stack) == 0)
97 def __init__(self, *level):
100 def setdebug(self, *level):
103 def level(self, level):
104 return level in self.__level
106 def info(self, level, str):
107 if level in self.__level:
111 debug = debug_info(debug_info.none)
113 # -----------------------------------------------------------------------------
115 # -----------------------------------------------------------------------------
118 """Used to keep track of our current location while parsing
119 configuration files"""
121 def __init__(self, file, line, command):
124 self.command = command
125 def next_line(self, command):
126 self.line = self.line + 1
127 self.command = command
129 return "%s:%d" % (self.file, self.line)
140 s = s + '\n' + p.at()
144 return self.stack.tos().file
147 return self.stack.tos().line
150 return self.stack.tos().command
152 def push(self, file):
153 self.stack.push(self.__place(os.path.normpath(file), 0, ""))
158 def next_line(self, command):
159 self.stack.tos().next_line(command)
162 return self.stack.tos().at()
166 """Print error message"""
169 print "===> ERROR: %s" % string
173 """Print error message and exit"""
178 """Print warning message"""
180 warnings = warnings + 1
181 print "===> WARNING: %s" % string
184 """Print notice message"""
185 #print "===> NOTE: %s" % string
188 """Exit parser if an error has been encountered"""
192 def safe_open(file, mode):
194 return open(file, mode)
196 fatal("Could not open file \"%s\"" % file)
198 # -----------------------------------------------------------------------------
200 # -----------------------------------------------------------------------------
203 """A rom image is the ultimate goal of coreboot"""
204 def __init__ (self, name):
205 # name of this rom image
208 # set by 'arch' directive
211 # set by 'payload' directive
214 # set by 'init' directive
217 # make rules added by 'makerule' directive
218 self.makebaserules = {}
220 # object files added by 'object' directive
221 self.objectrules = {}
223 # init object files added by 'initobject' directive
224 self.initobjectrules = {}
226 # driver files added by 'driver' directive
227 self.driverrules = {}
229 # loader scripts added by 'ldscript' directive
232 # user defines added by 'makedefine' directive
233 self.userdefines = []
235 # files to be included in crt0.S
236 self.initincludes = {}
238 # as above, but order is preserved
239 self.initincludesorder = []
241 # transitional flag to support old crtinclude format
242 self.useinitincludes = 0
244 # instance counter for parts
245 self.partinstance = 0
247 # chip config files included by the 'config' directive
248 self.configincludes = {}
253 # name of target directory specified by 'target' directive
256 # option values used in rom image
260 self.exported_options = []
271 def setarch(self, arch):
274 def setpayload(self, payload):
275 self.payload = payload
277 def setinitfile(self, initfile):
278 self.initfile = initfile
280 def getinitfile(self):
283 def addmakerule(self, id):
284 o = getdict(self.makebaserules, id)
286 warning("rule %s previously defined" % id)
288 setdict(self.makebaserules, id, o)
290 def getmakerules(self):
291 return self.makebaserules
293 def getmakerule(self, id):
294 o = getdict(self.makebaserules, id)
297 fatal("No such make rule \"%s\"" % id)
299 def addmakeaction(self, id, str):
300 o = getdict(self.makebaserules, id)
305 fatal("No such rule \"%s\" for addmakeaction" % id)
307 def addmakedepend(self, id, str):
308 o = getdict(self.makebaserules, id)
313 fatal("No such rule \"%s\" for addmakedepend" % id)
315 # this is called with an an object name.
316 # the easiest thing to do is add this object to the current
318 # such kludgery. If the name starts with '.' then make the
319 # dependency be on ./thing.x gag me.
320 def addobjectdriver(self, dict, object_name):
322 suffix = object_name[-2:]
325 base = object_name[:-2]
326 type = object_name[-1:]
327 if (object_name[0] == '.'):
328 source = base + suffix
330 source = os.path.join(dirstack.tos(), base + suffix)
332 debug.info(debug.object, "add object %s source %s" % (object_name, source))
333 l = getdict(dict, base)
335 warning("object/driver %s previously defined" % base)
336 setdict(dict, base, [object, source, type, base])
338 def addinitobjectrule(self, name):
339 self.addobjectdriver(self.initobjectrules, name)
341 def addobjectrule(self, name):
342 self.addobjectdriver(self.objectrules, name)
344 def adddriverrule(self, name):
345 self.addobjectdriver(self.driverrules, name)
347 def getinitobjectrules(self):
348 return self.initobjectrules
350 def getinitobjectrule(self, name):
351 o = getdict(self.initobjectrules, name)
354 fatal("No such init object rule \"%s\"" % name)
356 def getobjectrules(self):
357 return self.objectrules
359 def getobjectrule(self, name):
360 o = getdict(self.objectrules, name)
363 fatal("No such object rule \"%s\"" % name)
365 def getdriverrules(self):
366 return self.driverrules
368 def getdriverrule(self, name):
369 o = getdict(self.driverrules, name)
372 fatal("No such driver rule \"%s\"" % name)
374 def addldscript(self, path):
375 self.ldscripts.append(path)
377 def getldscripts(self):
378 return self.ldscripts
380 def adduserdefine(self, str):
381 self.userdefines.append(str)
383 def getuserdefines(self):
384 return self.userdefines
386 def addinitinclude(self, str, path):
388 self.useinitincludes = 1
390 debug.info(debug.object, "ADDCRT0: %s -> %s" % (str, path))
391 o = getdict(self.initincludes, path)
393 warning("init include for %s previously defined" % path)
394 o = initinclude(str, path)
395 setdict(self.initincludes, path, o)
396 self.initincludesorder.append(path)
398 def getinitincludes(self):
399 return self.initincludesorder
401 def getinitinclude(self, path):
402 o = getdict(self.initincludes, path)
405 fatal("No such init include \"%s\"" % path)
407 def addconfiginclude(self, part, path):
408 setdict(self.configincludes, part, path)
410 def getconfigincludes(self):
411 return self.configincludes
413 def getincludefilename(self):
414 if (self.useinitincludes):
417 return "crt0_includes.h"
420 return self.useinitincludes
423 return self.partinstance
425 def newpartinstance(self):
426 i = self.partinstance
427 self.partinstance = self.partinstance + 1
430 def setroot(self, part):
436 def settargetdir(self, path):
437 self.targetdir = path
439 def gettargetdir(self):
440 return self.targetdir
443 """A buildrom statement"""
444 def __init__ (self, filename, size, roms):
450 return len(self.roms)
452 def __getitem__(self,i):
456 """include file for initialization code"""
457 def __init__ (self, str, path):
468 """Rule to be included in Makefile"""
469 def __init__ (self, target):
474 def addaction(self, action):
475 self.actions.append(action)
477 def adddependency(self, dependency):
478 self.dependency.append(dependency)
483 def gdependency(self):
484 return self.dependency
490 """Configuration option"""
491 def __init__ (self, name):
492 self.name = name # name of option
493 self.loc = 0 # current location
494 self.used = 0 # option has been used
496 self.comment = '' # description of option
497 self.exportable = 0 # option is able to be exported
498 self.format = '%s' # option print format
499 self.write = [] # parts that can set this option
504 def setcomment(self, comment, loc):
505 if (self.comment != ''):
506 print "%s: " % self.name
507 print "Attempt to modify comment at %s" % loc
509 self.comment = comment
511 def setexportable(self):
514 def setnoexport(self):
517 def setformat(self, fmt):
524 if (self.exportable):
528 def setwrite(self, part):
529 self.write.append(part)
531 def isexportable(self):
532 return self.exportable
534 def iswritable(self, part):
535 return (part in self.write)
538 """Value of a configuration option. The option has a default
539 value which can be changed at any time. Once an option has been
540 set the default value is no longer used."""
541 def __init__(self, name, prev):
546 self.value = prev.value
550 def setvalue(self, value):
551 if ((self.set & 2) == 2):
552 warning("Changing option %s" % self.name)
557 def setdefault(self, value):
558 if ((self.set & 1) == 1):
559 notice("Changing default value of %s" % self.name)
561 if ((self.set & 2) == 0):
569 return (self.set & 2) == 2
573 """A configuration part"""
574 def __init__ (self, image, dir, parent, part, type_name, instance_name, chip_or_device):
575 debug.info(debug.object, "partobj dir %s parent %s part %s" \
576 % (dir, parent, part))
578 # romimage that is configuring this part
581 # links for static device tree
583 self.prev_sibling = 0
584 self.next_sibling = 0
587 self.chip_or_device = chip_or_device
589 # list of init code files
592 # initializers for static device tree
593 self.registercode = {}
598 # type name of this part
599 self.type_name = type_name
601 # object files needed to build this part
604 # directory containg part files
607 # instance number, used to distinguish anonymous
608 # instances of this part
609 self.instance = image.newpartinstance()
610 debug.info(debug.object, "INSTANCE %d" % self.instance)
612 # Options used by this part
613 self.uses_options = {}
615 # Name of chip config file (0 if not needed)
618 # Flag to indicate that we have generated type
619 # definitions for this part (only want to do it once)
625 # Resources of the device
629 # Enabled state of the device
632 # Flag if I am a dumplicate device
635 # If no instance name is supplied then generate
637 if (instance_name == 0):
638 self.instance_name = self.type_name + \
639 "_dev%d" % self.instance
640 self.chipinfo_name = "%s_info_%d" \
641 % (self.type_name, self.instance)
643 self.instance_name = instance_name
644 self.chipinfo_name = "%s_info_%d" % (self.instance_name, self.instance)
646 # Link this part into the device list
647 if (self.chip_or_device == 'device'):
648 if (image.last_device):
649 image.last_device.next_device = self
650 self.prev_device = image.last_device
651 image.last_device = self
653 # Link this part into the tree
654 if (parent and (part != 'arch')):
655 debug.info(debug.gencode, "add to parent")
657 # add current child as my sibling,
659 if (parent.children):
660 debug.info(debug.gencode, "add %s (%d) as sibling" % (parent.children.dir, parent.children.instance))
661 youngest = parent.children
662 while(youngest.next_sibling):
663 youngest = youngest.next_sibling
664 youngest.next_sibling = self
665 self.prev_sibling = youngest
667 parent.children = self
673 return "%s: %s" % (self.part, self.type)
675 return self.chip_or_device
677 def readable_name(self):
679 name = "%s_%d" % (self.type_name, self.instance)
680 if (self.chip_or_device == 'chip'):
681 name = "%s %s %s" % (name, self.part, self.dir)
683 name = "%s %s" % (name, self.path)
686 def dumpme(self, lvl):
687 """Dump information about this part for debugging"""
688 print "%d: %s" % (lvl, self.readable_name())
689 print "%d: part %s" % (lvl, self.part)
690 print "%d: instance %d" % (lvl, self.instance)
691 print "%d: chip_or_device %s" % (lvl, self.chip_or_device)
692 print "%d: dir %s" % (lvl,self.dir)
693 print "%d: type_name %s" % (lvl,self.type_name)
694 print "%d: parent: %s" % (lvl, self.parent.readable_name())
696 print "%d: child %s" % (lvl, self.children.readable_name())
697 if (self.next_sibling):
698 print "%d: siblings %s" % (lvl, self.next_sibling.readable_name())
699 print "%d: initcode " % lvl
700 for i in self.initcode:
702 print "%d: registercode " % lvl
703 for f, v in self.registercode.items():
704 print "\t%s = %s" % (f, v)
707 def firstchilddevice(self):
708 """Find the first device in the children link."""
711 if (kid.chip_or_device == 'device'):
717 def firstparentdevice(self):
718 """Find the first device in the parent link."""
720 while (parent and (parent.parent != parent) and (parent.chip_or_device != 'device')):
721 parent = parent.parent
722 if ((parent.parent != parent) and (parent.chip_or_device != 'device')):
724 while(parent and (parent.dup == 1)):
725 parent = parent.prev_sibling
727 fatal("Device %s has no device parent; this is a config file error" % self.readable_name())
730 def firstparentdevicelink(self):
731 """Find the first device in the parent link and record which link it is."""
734 while (parent and (parent.parent != parent) and (parent.chip_or_device != 'device')):
735 parent = parent.parent
736 if ((parent.parent != parent) and (parent.chip_or_device != 'device')):
738 while(parent and (parent.dup == 1)):
739 parent = parent.prev_sibling
742 fatal("Device %s has no device parent; this is a config file error" % self.readable_name())
746 def firstparentchip(self):
747 """Find the first chip in the parent link."""
750 if ((parent.parent == parent) or (parent.chip_or_device == 'chip')):
753 parent = parent.parent
754 fatal("Device %s has no chip parent; this is a config file error" % self.readable_name())
756 def firstsiblingdevice(self):
757 """Find the first device in the sibling link."""
758 sibling = self.next_sibling
759 while(sibling and (sibling.path == self.path)):
760 sibling = sibling.next_sibling
761 if ((not sibling) and (self.parent.chip_or_device == 'chip')):
762 sibling = self.parent.next_sibling
764 if (sibling.chip_or_device == 'device'):
767 sibling = sibling.children
770 def gencode(self, file, pass_num):
771 """Generate static initalizer code for this part. Two passes
772 are used - the first generates type information, and the second
773 generates instance information"""
775 if (self.chip_or_device == 'chip'):
779 file.write("struct device %s;\n" \
780 % self.instance_name)
782 file.write("struct device dev_root;\n")
784 # This is pass the second, which is pass number 1
785 # this is really just a case statement ...
787 if (self.chip_or_device == 'chip'):
788 if (self.chipconfig):
789 debug.info(debug.gencode, "gencode: chipconfig(%d)" % \
791 file.write("struct %s_config %s" % (self.type_name ,\
793 if (self.registercode):
794 file.write("\t= {\n")
795 for f, v in self.registercode.items():
796 file.write( "\t.%s = %s,\n" % (f, v))
802 if (self.instance == 0):
803 self.instance_name = "dev_root"
804 file.write("struct device **last_dev_p = &%s.next;\n" % (self.image.last_device.instance_name))
805 file.write("struct device dev_root = {\n")
806 file.write("\t.ops = &default_dev_ops_root,\n")
807 file.write("\t.bus = &dev_root.link[0],\n")
808 file.write("\t.path = { .type = DEVICE_PATH_ROOT },\n")
809 file.write("\t.enabled = 1,\n\t.links = 1,\n")
810 file.write("\t.on_mainboard = 1,\n")
811 file.write("\t.link = {\n\t\t[0] = {\n")
812 file.write("\t\t\t.dev=&dev_root,\n\t\t\t.link = 0,\n")
813 file.write("\t\t\t.children = &%s,\n" % self.firstchilddevice().instance_name)
814 file.write("\t\t},\n")
816 if (self.chipconfig):
817 file.write("\t.chip_ops = &%s_ops,\n" % self.type_name)
818 file.write("\t.chip_info = &%s_info_%s,\n" % (self.type_name, self.instance))
819 file.write("\t.next = &%s,\n" % self.firstchilddevice().instance_name)
823 # Don't print duplicate devices, just print their children
827 file.write("struct device %s = {\n" % self.instance_name)
828 file.write("\t.ops = 0,\n")
829 file.write("\t.bus = &%s.link[%d],\n" % \
830 (self.firstparentdevice().instance_name, \
831 self.firstparentdevicelink()))
832 file.write("\t.path = {%s},\n" % self.path)
833 file.write("\t.enabled = %d,\n" % self.enabled)
834 file.write("\t.on_mainboard = 1,\n")
836 file.write("\t.resources = %d,\n" % self.resources)
837 file.write("\t.resource = {%s\n\t },\n" % self.resource)
838 file.write("\t.link = {\n");
841 while(bus and (bus.path == self.path)):
842 child = bus.firstchilddevice()
843 if (child or (bus != self) or (bus.next_sibling and (bus.next_sibling.path == self.path))):
844 file.write("\t\t[%d] = {\n" % links)
845 file.write("\t\t\t.link = %d,\n" % links)
846 file.write("\t\t\t.dev = &%s,\n" % self.instance_name)
848 file.write("\t\t\t.children = &%s,\n" %child.instance_name)
849 file.write("\t\t},\n")
852 bus = bus.next_sibling
856 file.write("\t.links = %d,\n" % (links))
857 sibling = self.firstsiblingdevice();
859 file.write("\t.sibling = &%s,\n" % sibling.instance_name)
860 chip = self.firstparentchip()
861 if (chip and chip.chipconfig):
862 file.write("\t.chip_ops = &%s_ops,\n" % chip.type_name)
863 file.write("\t.chip_info = &%s_info_%s,\n" % (chip.type_name, chip.instance))
864 if (self.next_device):
865 file.write("\t.next=&%s\n" % self.next_device.instance_name)
869 def addinit(self, code):
870 """Add init file to this part"""
871 self.initcode.append(code)
873 def addconfig(self, path):
874 """Add chip config file to this part"""
875 self.chipconfig = os.path.join(self.dir, path)
876 self.image.addconfiginclude(self.type_name, self.chipconfig)
878 def addregister(self, field, value):
879 """Register static initialization information"""
880 if (self.chip_or_device != 'chip'):
881 fatal("Only chips can have register values")
882 field = dequote(field)
883 value = dequote(value)
884 setdict(self.registercode, field, value)
886 def set_enabled(self, enabled):
887 self.enabled = enabled
889 def start_resources(self):
893 def end_resources(self):
894 self.resource = "%s" % (self.resource)
896 def add_resource(self, type, index, value):
897 """ Add a resource to a device """
898 self.resource = "%s\n\t\t{ .flags=%s, .index=0x%x, .base=0x%x}," % (self.resource, type, index, value)
899 self.resources = self.resources + 1
901 def set_path(self, path):
903 if (self.prev_sibling and (self.prev_sibling.path == self.path)):
905 if (self.prev_device):
906 self.prev_device.next_device = self.next_device
907 if (self.next_device):
908 self.next_device.prev_device = self.prev_device
909 if (self.image.last_device == self):
910 self.image.last_device = self.prev_device
914 def addpcipath(self, slot, function):
915 """ Add a relative pci style path from our parent to this device """
916 if ((slot < 0) or (slot > 0x1f)):
917 fatal("Invalid device id")
918 if ((function < 0) or (function > 7)):
919 fatal("Invalid pci function %s" % function )
920 self.set_path(".type=DEVICE_PATH_PCI,.u={.pci={ .devfn = PCI_DEVFN(0x%x,%d)}}" % (slot, function))
922 def addpnppath(self, port, device):
923 """ Add a relative path to a pnp device hanging off our parent """
924 if ((port < 0) or (port > 65536)):
925 fatal("Invalid port")
926 if ((device < 0) or (device > 0xffff)):
927 fatal("Invalid device")
928 self.set_path(".type=DEVICE_PATH_PNP,.u={.pnp={ .port = 0x%x, .device = 0x%x }}" % (port, device))
930 def addi2cpath(self, device):
931 """ Add a relative path to a i2c device hanging off our parent """
932 if ((device < 0) or (device > 0x7f)):
933 fatal("Invalid device")
934 self.set_path(".type=DEVICE_PATH_I2C,.u={.i2c={ .device = 0x%x }}" % (device))
936 def addapicpath(self, apic_id):
937 """ Add a relative path to a cpu device hanging off our parent """
938 if ((apic_id < 0) or (apic_id > 255)):
939 fatal("Invalid device")
940 self.set_path(".type=DEVICE_PATH_APIC,.u={.apic={ .apic_id = 0x%x }}" % (apic_id))
942 def addpci_domainpath(self, pci_domain):
943 """ Add a pci_domain number to a chip """
944 if ((pci_domain < 0) or (pci_domain > 0xffff)):
945 fatal("Invalid pci_domain: 0x%x is out of the range 0 to 0xffff" % pci_domain)
946 self.set_path(".type=DEVICE_PATH_PCI_DOMAIN,.u={.pci_domain={ .domain = 0x%x }}" % (pci_domain))
948 def addapic_clusterpath(self, cluster):
949 """ Add an apic cluster to a chip """
950 if ((cluster < 0) or (cluster > 15)):
951 fatal("Invalid apic cluster: %d is out of the range 0 to ff" % cluster)
952 self.set_path(".type=DEVICE_PATH_APIC_CLUSTER,.u={.apic_cluster={ .cluster = 0x%x }}" % (cluster))
954 def addcpupath(self, cpu_id):
955 """ Add a relative path to a cpu device hanging off our parent """
956 if ((cpu_id < 0) or (cpu_id > 255)):
957 fatal("Invalid device")
958 self.set_path(".type=DEVICE_PATH_CPU,.u={.cpu={ .id = 0x%x }}" % (cpu_id))
961 def addcpu_buspath(self, id):
962 """ Add a cpu_bus to a chip """
963 if ((id < 0) or (id > 255)):
964 fatal("Invalid device")
965 self.set_path(".type=DEVICE_PATH_CPU_BUS,.u={.cpu_bus={ .id = 0x%x }}" % (id))
967 def usesoption(self, name):
968 """Declare option that can be used by this part"""
969 global global_options
970 o = getdict(global_options, name)
972 fatal("can't use undefined option %s" % name)
973 o1 = getdict(self.uses_options, name)
976 setdict(self.uses_options, name, o)
977 exportoption(o, self.image.exported_options)
979 # -----------------------------------------------------------------------------
981 # -----------------------------------------------------------------------------
983 def getdict(dict, name):
984 if name not in dict.keys():
985 debug.info(debug.dict, "Undefined: %s" % name)
987 v = dict.get(name, 0)
988 debug.info(debug.dict, "getdict %s returning %s" % (name, v))
991 def setdict(dict, name, value):
992 debug.info(debug.dict, "setdict sets %s to %s" % (name, value))
996 # to create an option, it has to not exist.
997 # When an option value is fetched, the fact that it was used is
999 # Legal things to do:
1000 # set a default value, then set a real value before the option is used.
1001 # set a value, try to set a default, default silently fails.
1003 # use the value, then try to set the value
1005 def newoption(name):
1006 global global_options, global_options_by_order
1007 o = getdict(global_options, name)
1009 fatal("option %s already defined" % name)
1011 setdict(global_options, name, o)
1012 global_options_by_order.append(name)
1014 def newoptionvalue(name, image):
1015 g = getdict(global_option_values, name)
1016 v = option_value(name, g)
1018 setdict(image.getvalues(), name, v)
1020 setdict(global_option_values, name, v)
1023 def getoptionvalue(name, op, image):
1024 global global_option_values
1025 #print "getoptionvalue name %s op %s image %s\n" % (name, op,image)
1027 # we want to debug config files, not the config tool, so no:
1029 fatal("Option %s undefined (missing use command?)" % name)
1031 v = getdict(image.getvalues(), name)
1033 v = getdict(global_option_values, name)
1036 def getoption(name, image):
1037 """option must be declared before being used in a part
1038 if we're not processing a part, then we must
1039 be at the top level where all options are available"""
1041 global global_uses_options, alloptions, curimage
1043 #print "getoption: name %s image %s alloptions %s curimage %s\n\n" % (name, image, alloptions, curimage)
1044 curpart = partstack.tos()
1046 o = getdict(global_options, name)
1048 o = getdict(curpart.uses_options, name)
1050 print "curpart.uses_options is %s\n" % curpart.uses_options
1052 o = getdict(global_uses_options, name)
1053 v = getoptionvalue(name, o, image)
1055 v = getoptionvalue(name, o, 0)
1057 fatal("No value for option %s" % name)
1059 if (not (type(val) is types.StringType)):
1061 if (val == '' or val[0] != '{'):
1065 val = parse('delexpr', val)
1070 def setoption(name, value, imp):
1071 """Set an option from within a configuration file. Normally this
1072 is only permitted in the target (top level) configuration file.
1073 If 'imp' is true, then set an option implicitly (e.g. 'arch'
1074 and 'mainboard' statements). Implicit options can be set anywhere
1075 the statements are legal, but also performs an implicit 'uses'
1078 global loc, global_options, global_option_values, curimage
1080 curpart = partstack.tos()
1081 if (not imp and curpart):
1082 fatal("Options may only be set in target configuration file")
1086 o = getdict(curpart.uses_options, name)
1088 o = getdict(global_uses_options, name)
1090 fatal("Attempt to set nonexistent option %s (missing USES?)" % name)
1091 v = getoptionvalue(name, o, curimage)
1093 v = newoptionvalue(name, curimage)
1096 def exportoption(op, exported_options):
1097 if (not op.isexportable()):
1099 if (not op in exported_options):
1100 exported_options.append(op)
1102 def setdefault(name, value, isdef):
1103 """Set the default value of an option from within a configuration
1104 file. This is permitted from any configuration file, but will
1105 result in a warning if the default is set more than once.
1106 If 'isdef' is set, we're defining the option in Options.lb so
1107 there is no need for 'uses'."""
1109 global loc, global_options, curimage
1112 o = getdict(global_options, name)
1117 curpart = partstack.tos()
1119 o = getdict(curpart.uses_options, name)
1121 o = getdict(global_uses_options, name)
1123 fatal("Attempt to set default for nonexistent option %s (missing USES?)" % name)
1126 v = getoptionvalue(name, o, image)
1128 v = newoptionvalue(name, image)
1131 def setnodefault(name):
1132 global loc, global_options
1133 o = getdict(global_options, name)
1136 v = getdict(global_option_values, name)
1138 warning("removing default for %s" % name)
1139 del global_option_values[name]
1141 def setcomment(name, value):
1142 global loc, global_options
1143 o = getdict(global_options, name)
1145 fatal("setcomment: %s not here" % name)
1146 o.setcomment(value, loc)
1148 def setexported(name):
1149 global global_options
1150 o = getdict(global_options, name)
1152 fatal("setexported: %s not here" % name)
1154 global_exported_options.append(o)
1156 def setnoexport(name):
1157 global global_options
1158 o = getdict(global_options, name)
1160 fatal("setnoexport: %s not here" % name)
1162 if (o in global_exported_options):
1163 global_exported_options.remove(o)
1165 def setexportable(name):
1166 global global_options
1167 o = getdict(global_options, name)
1169 fatal("setexportable: %s not here" % name)
1172 def setformat(name, fmt):
1173 global global_options
1174 o = getdict(global_options, name)
1176 fatal("setformat: %s not here" % name)
1179 def getformated(name, image):
1180 global global_options, global_option_values
1181 o = getdict(global_options, name)
1182 v = getoption(name, image)
1186 def setwrite(name, part):
1187 global global_options
1188 o = getdict(global_options, name)
1190 fatal("setwrite: %s not here" % name)
1193 def hasvalue(name, image):
1194 global global_options
1195 o = getdict(global_options, name)
1200 v = getdict(image.getvalues(), name)
1202 v = getdict(global_option_values, name)
1205 def isset(name, part):
1206 global global_uses_options, global_option_values, curimage
1208 o = getdict(part.uses_options, name)
1210 o = getdict(global_uses_options, name)
1215 v = getdict(curimage.getvalues(), name)
1217 v = getdict(global_option_values, name)
1218 return (v != 0 and v.isset())
1220 def usesoption(name):
1221 global global_options, global_uses_options
1222 curpart = partstack.tos()
1224 curpart.usesoption(name)
1226 o = getdict(global_options, name)
1228 fatal("Can't use undefined option %s" % name)
1229 o1 = getdict(global_uses_options, name)
1232 setdict(global_uses_options, name, o)
1233 exportoption(o, global_exported_options)
1235 def validdef(name, defval):
1236 global global_options
1237 o = getdict(global_options, name)
1239 fatal("validdef: %s not here" % name)
1240 if ((defval & 1) != 1):
1241 fatal("Must specify default value for option %s" % name)
1242 if ((defval & 2) != 2):
1243 fatal("Must specify export for option %s" % name)
1244 if ((defval & 4) != 4):
1245 fatal("Must specify comment for option %s" % name)
1247 def loadoptions(path, file, rule):
1248 file = os.path.join('src', path, file)
1249 optionsfile = os.path.join(treetop, file)
1250 fp = safe_open(optionsfile, 'r')
1252 if (not parse(rule, fp.read())):
1253 fatal("Could not parse file")
1257 global curimage, dirstack
1258 if (path[0] == '/'):
1259 curimage.setinitfile(treetop + '/src/' + path)
1261 curimage.setinitfile(dirstack.tos() + '/' + path)
1262 print "Adding init file: %s" % path
1264 def addconfig(path):
1266 curpart = partstack.tos()
1267 curpart.addconfig(path)
1269 def addregister(field, value):
1271 curpart = partstack.tos()
1272 curpart.addregister(field, value)
1274 def addcrt0include(path):
1275 """we do the crt0include as a dictionary, so that if needed we
1276 can trace who added what when. Also it makes the keys
1279 curimage.addinitinclude(0, path)
1281 def addinitinclude(str, path):
1283 curimage.addinitinclude(dequote(str), path)
1285 def addldscript(path):
1286 global curimage, dirstack
1287 curdir = dirstack.tos()
1288 if (path[0] == '/'):
1289 fullpath = treetop + '/src/' + path
1291 fullpath = curdir + '/' + path
1292 debug.info(debug.statement, "fullpath :%s: curdir :%s: path :%s:" % (fullpath, curdir, path))
1293 curimage.addldscript(fullpath)
1297 curimage.setpayload(path)
1298 adduserdefine("PAYLOAD:=%s"%path)
1300 def startromimage(name):
1301 global romimages, curimage, target_dir, target_name
1302 curpart = partstack.tos()
1303 print "Configuring ROMIMAGE %s Curimage %s" % (name, curimage)
1304 print "Curpart is %s\n" % curpart
1305 o = getdict(romimages, name)
1307 fatal("romimage %s previously defined" % name)
1308 curimage = romimage(name)
1309 curimage.settargetdir(os.path.join(target_dir, name))
1310 #o = partobj(curimage, target_dir, 0, 'board', target_name)
1311 #curimage.setroot(o)
1312 setdict(romimages, name, curimage)
1313 dodir('/config', 'Config.lb')
1318 print "End ROMIMAGE"
1322 def mainboardsetup(path):
1323 global full_mainboard_path, mainboard_path
1324 mainboard_path = os.path.join('mainboard', path)
1325 loadoptions(mainboard_path, 'Options.lb', 'mainboardvariables')
1326 full_mainboard_path = os.path.join(treetop, 'src', 'mainboard', path)
1327 vendor = re.sub("/.*", "", path)
1328 part_number = re.sub("[^/]*/", "", path)
1329 setdefault('MAINBOARD', full_mainboard_path, 0)
1330 setdefault('MAINBOARD_VENDOR', vendor, 0)
1331 setdefault('MAINBOARD_PART_NUMBER', part_number, 0)
1334 global curimage, dirstack, partstack
1336 partdir = mainboard_path
1337 srcdir = os.path.join(treetop, 'src')
1338 fulldir = os.path.join(srcdir, partdir)
1339 type_name = flatten_name(partdir)
1340 newpart = partobj(curimage, fulldir, partstack.tos(), 'mainboard', \
1341 type_name, 0, 'chip')
1342 #print "Configuring PART %s" % (type)
1343 partstack.push(newpart)
1344 #print " new PART tos is now %s\n" %partstack.tos().info()
1345 dirstack.push(fulldir)
1346 loadoptions(mainboard_path, 'Options.lb', 'mainboardvariables')
1347 # special case for 'cpu' parts.
1348 # we could add a new function too, but this is rather trivial.
1349 # if the part is a cpu, and we haven't seen it before,
1350 # arrange to source the directory /cpu/'type'
1351 doconfigfile(srcdir, partdir, file, 'cfgfile')
1352 curimage.setroot(partstack.tos())
1355 def addbuildrom(filename, size, roms):
1357 print "Build ROM size %d" % size
1358 b = buildrom(filename, size, roms)
1361 def addinitobject(object_name):
1363 curimage.addinitobjectrule(object_name)
1365 def addobject(object_name):
1367 curimage.addobjectrule(object_name)
1369 def adddriver(driver_name):
1371 curimage.adddriverrule(driver_name)
1374 global target_dir, target_name
1375 print "Configuring TARGET %s" % name
1377 target_dir = os.path.join(os.path.dirname(loc.file()), name)
1378 if not os.path.isdir(target_dir):
1379 print "Creating directory %s" % target_dir
1380 os.makedirs(target_dir)
1381 print "Will place Makefile, crt0.S, etc. in %s" % target_dir
1386 if (cpu_type and (cpu_type != path)):
1387 fatal("Two different CPU types: %s and %s" % (cpu_type, path))
1388 srcdir = "/cpu/%s" % path
1389 dodir(srcdir, "Config.lb")
1392 def devicepart(type):
1393 global curimage, dirstack, partstack
1394 newpart = partobj(curimage, 0, partstack.tos(), type, \
1396 #print "Configuring PART %s" % (type)
1397 partstack.push(newpart)
1398 #print " new PART tos is now %s\n" %partstack.tos().info()
1399 # just push TOS, so that we can pop later.
1400 dirstack.push(dirstack.tos())
1402 def part(type, path, file, name):
1403 global curimage, dirstack, partstack
1404 partdir = os.path.join(type, path)
1405 srcdir = os.path.join(treetop, 'src')
1406 fulldir = os.path.join(srcdir, partdir)
1407 type_name = flatten_name(partdir)
1408 newpart = partobj(curimage, fulldir, partstack.tos(), type, \
1409 type_name, name, 'chip')
1410 #print "Configuring PART %s, path %s" % (type, path)
1411 partstack.push(newpart)
1412 #print " new PART tos is now %s\n" %partstack.tos().info()
1413 dirstack.push(fulldir)
1414 # special case for 'cpu' parts.
1415 # we could add a new function too, but this is rather trivial.
1416 # if the part is a cpu, and we haven't seen it before,
1417 # arrange to source the directory /cpu/'type'
1421 doconfigfile(srcdir, partdir, file, 'cfgfile')
1424 global dirstack, partstack
1425 curpart = partstack.tos()
1427 fatal("Trying to pop non-existent part")
1428 #print "End PART %s" % curpart.part
1429 # Warn if options are used without being set in this part
1430 for op in curpart.uses_options.keys():
1431 if (not isset(op, curpart)):
1432 notice("Option %s using default value %s" % (op, getformated(op, curpart.image)))
1433 oldpart = partstack.pop()
1435 #print "partstack.pop, TOS is now %s\n" % oldpart.info()
1437 def dodir(path, file):
1438 """dodir is like part but there is no new part"""
1440 # if the first char is '/', it is relative to treetop,
1441 # else relative to curdir
1442 # os.path.join screws up if the name starts with '/', sigh.
1443 print "Configuring DIR %s" % os.path.join(path, file)
1444 if (path[0] == '/'):
1445 fullpath = os.path.join(treetop, 'src')
1446 path = re.sub('^/*', '', path)
1448 fullpath = dirstack.tos()
1449 debug.info(debug.statement, "DODIR: path %s, fullpath %s" % (path, fullpath))
1450 dirstack.push(os.path.join(fullpath, path))
1451 doconfigfile(fullpath, path, file, 'cfgfile')
1456 return getoption(name, curimage)
1460 curimage.addmakerule(id)
1462 def adduserdefine(str):
1464 curimage.adduserdefine(str)
1466 def addaction(id, str):
1468 curimage.addmakeaction(id, str)
1470 def adddep(id, str):
1472 curimage.addmakedepend(id, str)
1474 def setarch(my_arch):
1475 """arch is 'different' ... darn it."""
1477 print "SETTING ARCH %s\n" % my_arch
1478 curimage.setarch(my_arch)
1479 setdefault('ARCH', my_arch, 1)
1480 part('arch', my_arch, 'Config.lb', 0)
1482 def doconfigfile(path, confdir, file, rule):
1483 rname = os.path.join(confdir, file)
1485 fullpath = os.path.join(path, rname)
1486 fp = safe_open(fullpath, 'r')
1487 if (not parse(rule, fp.read())):
1488 fatal("Could not parse file")
1492 #=============================================================================
1494 #=============================================================================
1495 def ternary(val, yes, no):
1496 debug.info(debug.statement, "ternary %s" % expr)
1497 debug.info(debug.statement, "expr %s a %d yes %d no %d"% (expr, a, yes, no))
1499 debug.info(debug.statement, "Ternary returns %d" % yes)
1502 debug.info(debug.statement, "Ternary returns %d" % no)
1506 """atoi is in the python library, but not strtol? Weird!"""
1507 return eval('int(%s)' % name)
1510 """ Is the given string an integer?"""
1518 a = re.sub("^\"", "", str)
1519 a = re.sub("\"$", "", a)
1520 # highly un-intuitive, need four \!
1521 a = re.sub("\\\\\"", "\"", a)
1524 def flatten_name(str):
1525 a = re.sub("[/-]", "_", str)
1529 """If the first part of <path> matches treetop, replace
1530 that part with $(TOP)"""
1531 if path[0:len(treetop)] == treetop:
1532 path = path[len(treetop):len(path)]
1533 if (path[0:1] == "/"):
1534 path = path[1:len(path)]
1535 path = "$(TOP)/" + path
1539 # to make if work without 2 passses, we use an old hack from SIMD, the
1540 # context bit. If the bit is 1, then ops get done, otherwise
1541 # ops don't get done. From the top level, context is always
1542 # 1. In an if, context depends on eval of the if condition
1548 # less general tokens should come first, otherwise they get matched
1550 token ACTION: 'action'
1551 token ADDACTION: 'addaction'
1552 token ALWAYS: 'always'
1554 token BUILDROM: 'buildrom'
1555 token COMMENT: 'comment'
1556 token CONFIG: 'config'
1558 token CPU_BUS: 'cpu_bus'
1560 token DEFAULT: 'default'
1561 token DEFINE: 'define'
1562 token DEPENDS: 'depends'
1563 token DEVICE: 'device'
1565 token DRIVER: 'driver'
1571 token EXPORT: 'export'
1572 token FORMAT: 'format'
1575 token INITOBJECT: 'initobject'
1576 token INITINCLUDE: 'initinclude'
1579 token LDSCRIPT: 'ldscript'
1580 token LOADOPTIONS: 'loadoptions'
1581 token MAINBOARD: 'mainboard'
1582 token MAINBOARDINIT: 'mainboardinit'
1583 token MAKEDEFINE: 'makedefine'
1584 token MAKERULE: 'makerule'
1586 token NEVER: 'never'
1588 token NORTHBRIDGE: 'northbridge'
1589 token OBJECT: 'object'
1590 token OPTION: 'option'
1591 token PAYLOAD: 'payload'
1593 token PRINT: 'print'
1594 token REGISTER: 'register'
1595 token ROMIMAGE: 'romimage'
1596 token SOUTHBRIDGE: 'southbridge'
1597 token SUPERIO: 'superio'
1598 token TARGET: 'target'
1601 token WRITE: 'write'
1603 token HEX_NUM: '[0-9a-fA-F]+'
1604 token HEX_PREFIX: '0x'
1605 # Why is path separate? Because paths to resources have to at least
1606 # have a slash, we thinks
1607 token PATH: r'[-a-zA-Z0-9_.][-a-zA-Z0-9/_.]+[-a-zA-Z0-9_.]+'
1608 # Dir's on the other hand are abitrary
1609 # this may all be stupid.
1610 token RULE: r'[-a-zA-Z0-9_$()./]+[-a-zA-Z0-9_ $()./]+[-a-zA-Z0-9_$()./]+'
1611 token DIRPATH: r'[-a-zA-Z0-9_$()./]+'
1612 token ID: r'[a-zA-Z_.]+[a-zA-Z0-9_.]*'
1613 token DELEXPR: r'{([^}]+|\\.)*}'
1614 token STR: r'"([^\\"]+|\\.)*"'
1615 token RAWTEXT: r'.*'
1622 token APIC_CLUSTER: 'apic_cluster'
1624 token CPU_BUS: 'cpu_bus'
1625 token PCI_DOMAIN: 'pci_domain'
1628 rule expr: logical {{ l = logical }}
1629 ( "&&" logical {{ l = l and logical }}
1630 | "||" logical {{ l = l or logical }}
1633 rule logical: factor {{ n = factor }}
1634 ( "[+]" factor {{ n = n+factor }}
1635 | "-" factor {{ n = n-factor }}
1638 rule factor: term {{ v = term }}
1639 ( "[*]" term {{ v = v*term }}
1640 | "/" term {{ v = v/term }}
1641 | "<<" term {{ v = v << term }}
1642 | ">=" term {{ v = (v < term)}}
1645 # A term is a number, variable, or an expression surrounded by parentheses
1646 rule term: NUM {{ return long(NUM, 10) }}
1647 | HEX_PREFIX HEX_NUM {{ return long(HEX_NUM, 16) }}
1648 | ID {{ return lookup(ID) }}
1649 | unop {{ return unop }}
1650 | "\\(" expr "\\)" {{ return expr }}
1652 rule unop: "!" expr {{ return not(expr) }}
1654 rule partend<<C>>: (stmt<<C>>)* END {{ if (C): partpop()}}
1656 # This is needed because the legacy cpu command could not distinguish
1657 # between cpu vendors. It should just be PATH, but getting this change
1658 # into the source tree will be tricky...
1659 # DO NOT USE ID AS IT MAY GO AWAY IN THE FUTURE
1660 rule partid: ID {{ return ID }}
1661 | PATH {{ return PATH }}
1663 # rule parttype: NORTHBRIDGE {{ return 'northbridge' }}
1664 # | SUPERIO {{ return 'superio' }}
1665 # | PMC {{ return 'pmc' }}
1666 # | SOUTHBRIDGE {{ return 'southbridge' }}
1667 # | CPU {{ return 'cpu' }}
1668 # | CHIP {{ return '' }}
1670 rule parttype: CHIP {{ return '' }}
1672 rule partdef<<C>>: {{ name = 0 }}
1674 [ STR {{ name = dequote(STR) }}
1675 ] {{ if (C): part(parttype, partid, 'Config.lb', name) }}
1678 rule arch<<C>>: ARCH ID {{ if (C): setarch(ID) }}
1681 rule mainboardinit<<C>>:
1682 MAINBOARDINIT DIRPATH {{ if (C): addcrt0include(DIRPATH)}}
1684 rule initinclude<<C>>:
1687 DIRPATH {{ if (C): addinitinclude(STR, DIRPATH)}}
1689 rule initobject<<C>>:
1690 INITOBJECT DIRPATH {{ if (C): addinitobject(DIRPATH)}}
1692 rule object<<C>>: OBJECT DIRPATH {{ if (C): addobject(DIRPATH)}}
1694 rule driver<<C>>: DRIVER DIRPATH {{ if (C): adddriver(DIRPATH)}}
1696 rule dir<<C>>: DIR DIRPATH {{ if (C): dodir(DIRPATH, 'Config.lb') }}
1698 rule default<<C>>: DEFAULT ID EQ value {{ if (C): setdefault(ID, value, 0) }}
1700 rule ldscript<<C>>: LDSCRIPT DIRPATH {{ if (C): addldscript(DIRPATH) }}
1702 rule iif<<C>>: IF ID {{ c = lookup(ID) }}
1704 [ ELSE (stmt<<C and not c>>)* ]
1707 rule makerule<<C>>: MAKERULE RULE {{ if (C): addrule(RULE) }}
1708 ( DEPENDS STR {{ if (C): adddep(RULE, STR) }}
1709 | ACTION STR {{ if (C): addaction(RULE, STR) }}
1713 rule makedefine<<C>>:
1714 MAKEDEFINE RAWTEXT {{ if (C): adduserdefine(RAWTEXT) }}
1716 rule addaction<<C>>:
1717 ADDACTION ID STR {{ if (C): addaction(ID, STR) }}
1719 rule init<<C>>: INIT DIRPATH {{ if (C): addinit(DIRPATH) }}
1721 rule field: STR {{ return STR }}
1723 rule register<<C>>: REGISTER field '=' STR {{ if (C): addregister(field, STR) }}
1725 rule enable<<C>>: {{ val = 1 }}
1728 ) {{ if(C): partstack.tos().set_enabled(val) }}
1730 rule resource<<C>>: {{ type = "" }}
1731 ( IO {{ type = "IORESOURCE_FIXED | IORESOURCE_ASSIGNED | IORESOURCE_IO" }}
1732 | MEM {{ type = "IORESOURCE_FIXED | IORESOURCE_ASSIGNED | IORESOURCE_MEM" }}
1733 | IRQ {{ type = "IORESOURCE_FIXED | IORESOURCE_ASSIGNED | IORESOURCE_IRQ" }}
1734 | DRQ {{ type = "IORESOURCE_FIXED | IORESOURCE_ASSIGNED | IORESOURCE_DRQ" }}
1736 term '=' {{ index = term }}
1737 term {{ value = term }}
1738 {{ if (C): partstack.tos().add_resource(type, index, value) }}
1741 rule resources<<C>>: {{ if (C): partstack.tos().start_resources() }}
1743 {{ if (C): partstack.tos().end_resources() }}
1746 rule pci<<C>>: PCI {{ if (C): devicepart('pci') }}
1748 HEX_NUM {{ slot = int(HEX_NUM,16) }}
1749 '.' HEX_NUM {{ function = int(HEX_NUM, 16) }}
1750 {{ if (C): partstack.tos().addpcipath(slot, function) }}
1751 rule pci_domain<<C>>:
1752 PCI_DOMAIN {{ if (C): devicepart('pci_domain') }}
1753 HEX_NUM {{ pci_domain = int(HEX_NUM, 16) }}
1754 {{ if (C): partstack.tos().addpci_domainpath(pci_domain) }}
1756 rule pnp<<C>>: PNP {{ if (C): devicepart('pnp') }}
1757 HEX_NUM {{ port = int(HEX_NUM,16) }}
1758 '.' HEX_NUM {{ device = int(HEX_NUM, 16) }}
1759 {{ if (C): partstack.tos().addpnppath(port, device) }}
1761 rule i2c<<C>>: I2C {{ if (C): devicepart('i2c') }}
1762 HEX_NUM {{ device = int(HEX_NUM, 16) }}
1763 {{ if (C): partstack.tos().addi2cpath(device) }}
1765 rule apic<<C>>: APIC {{ if (C): devicepart('apic') }}
1766 HEX_NUM {{ apic_id = int(HEX_NUM, 16) }}
1767 {{ if (C): partstack.tos().addapicpath(apic_id) }}
1769 rule apic_cluster<<C>>: APIC_CLUSTER {{ if (C): devicepart('apic_cluster') }}
1770 HEX_NUM {{ cluster = int(HEX_NUM, 16) }}
1771 {{ if (C): partstack.tos().addapic_clusterpath(cluster) }}
1773 rule cpu<<C>>: CPU {{ if (C): devicepart('cpu') }}
1774 HEX_NUM {{ id = int(HEX_NUM, 16) }}
1775 {{ if (C): partstack.tos().addcpupath(id) }}
1777 rule cpu_bus<<C>>: CPU_BUS {{ if (C): devicepart('cpu_bus') }}
1778 HEX_NUM {{ id = int(HEX_NUM, 16) }}
1779 {{ if (C): partstack.tos().addcpu_buspath(id) }}
1782 pci<<C>> {{ return pci }}
1783 | pci_domain<<C>> {{ return pci_domain }}
1784 | pnp<<C>> {{ return pnp }}
1785 | i2c<<C>> {{ return i2c }}
1786 | apic<<C>> {{ return apic }}
1787 | apic_cluster<<C>> {{ return apic_cluster }}
1788 | cpu<<C>> {{ return cpu }}
1789 | cpu_bus<<C>> {{ return cpu_bus }}
1791 rule prtval: expr {{ return str(expr) }}
1792 | STR {{ return STR }}
1794 rule prtlist: prtval {{ el = "%(" + prtval }}
1795 ( "," prtval {{ el = el + "," + prtval }}
1796 )* {{ return el + ")" }}
1798 rule prtstmt<<C>>: PRINT STR {{ val = STR }}
1799 [ "," prtlist {{ val = val + prtlist }}
1800 ] {{ if (C): print eval(val) }}
1802 rule config<<C>>: CONFIG PATH {{ if (C): addconfig(PATH) }}
1804 rule device<<C>>: DEVICE dev_path<<C>>
1809 rule stmt<<C>>: arch<<C>> {{ return arch}}
1810 | addaction<<C>> {{ return addaction }}
1811 | config<<C>> {{ return config}}
1812 | default<<C>> {{ return default}}
1813 | dir<<C>> {{ return dir}}
1814 | driver<<C>> {{ return driver }}
1815 | iif<<C>> {{ return iif }}
1816 | init<<C>> {{ return init }}
1817 | initinclude<<C>> {{ return initinclude }}
1818 | initobject<<C>> {{ return initobject }}
1819 | ldscript<<C>> {{ return ldscript}}
1820 | mainboardinit<<C>> {{ return mainboardinit }}
1821 | makedefine<<C>> {{ return makedefine }}
1822 | makerule<<C>> {{ return makerule }}
1823 | object<<C>> {{ return object }}
1824 | option<<C>> {{ return option }}
1825 | partdef<<C>> {{ return partdef }}
1826 | prtstmt<<C>> {{ return prtstmt }}
1827 | register<<C>> {{ return register }}
1828 | device<<C>> {{ return device }}
1830 # ENTRY for parsing Config.lb file
1831 rule cfgfile: (uses<<1>>)*
1835 rule cfgfile: (uses<<1>>)*
1839 rule usesid<<C>>: ID {{ if (C): usesoption(ID) }}
1841 rule uses<<C>>: USES (usesid<<C>>)+
1843 rule mainboardvariables: (uses<<1>>)*
1848 rule value: STR {{ return dequote(STR) }}
1849 | expr {{ return expr }}
1850 | DELEXPR {{ return DELEXPR }}
1852 rule option<<C>>: OPTION ID EQ value {{ if (C): setoption(ID, value, 0) }}
1854 rule opif<<C>>: IF ID {{ c = lookup(ID) }}
1855 (opstmt<<C and c>>)*
1856 [ ELSE (opstmt<<C and not c>>)* ]
1859 rule opstmt<<C>>: option<<C>>
1863 rule payload<<C>>: PAYLOAD DIRPATH {{ if (C): payload(DIRPATH) }}
1866 MAINBOARD PATH {{ mainboardsetup(PATH) }}
1868 rule romif<<C>>: IF ID {{ c = lookup(ID) }}
1869 (romstmt<<C and c>>)*
1870 [ ELSE (romstmt<<C and not c>>)* ]
1873 rule romstmt<<C>>: romif<<C>>
1877 rule romimage: ROMIMAGE STR {{ startromimage(dequote(STR)) }}
1879 END {{ endromimage() }}
1881 rule roms: STR {{ s = '[' + STR }}
1882 ( STR {{ s = s + "," + STR }}
1883 )* {{ return eval(s + ']') }}
1885 rule buildrom: BUILDROM DIRPATH expr roms {{ addbuildrom(DIRPATH, expr, roms) }}
1887 rule romstmts: romimage
1891 # ENTRY for parsing root part
1892 rule board: {{ loadoptions("config", "Options.lb", "options") }}
1893 TARGET DIRPATH {{ target(DIRPATH) }}
1898 # ENTRY for parsing a delayed value
1899 rule delexpr: "{" expr "}" EOF {{ return expr }}
1901 rule wrstr<<ID>>: STR {{ setwrite(ID, dequote(STR)) }}
1903 rule defstmts<<ID>>: {{ d = 0 }}
1905 ( value {{ setdefault(ID, value, 1) }}
1906 | NONE {{ setnodefault(ID) }}
1908 | FORMAT STR {{ setformat(ID, dequote(STR)) }}
1910 ( ALWAYS {{ setexported(ID) }}
1911 | USED {{ setexportable(ID) }}
1912 | NEVER {{ setnoexport(ID) }}
1914 | COMMENT STR {{ setcomment(ID, dequote(STR)); d = d | 4 }}
1915 | WRITE (wrstr<<ID>>)+
1918 rule define: DEFINE ID {{ newoption(ID) }}
1919 defstmts<<ID>> END {{ validdef(ID, defstmts) }}
1921 # ENTRY for parsing Options.lb file
1922 rule options: (define)* EOF {{ return 1 }}
1925 #=============================================================================
1927 #=============================================================================
1928 def writemakefileheader(file, fname):
1929 file.write("# File: %s is autogenerated\n" % fname)
1931 def writemakefilefooter(file, fname):
1932 file.write("\n\n%s: %s %s\n"
1933 % (os.path.basename(fname), os.path.abspath(sys.argv[0]), top_config_file))
1934 file.write("\t(cd %s ; export PYTHONPATH=%s/util/newconfig ; python %s %s %s)\n\n"
1935 % (os.getcwd(), treetop, sys.argv[0], sys.argv[1], sys.argv[2]))
1937 def writemakefilesettings(path):
1938 """ Write Makefile.settings to seperate the settings
1939 from the actual makefile creation."""
1941 global treetop, target_dir
1943 filename = os.path.join(path, "Makefile.settings")
1944 print "Creating", filename
1945 file = safe_open(filename, 'w+')
1946 writemakefileheader(file, filename)
1947 file.write("TOP:=%s\n" % (treetop))
1948 file.write("TARGET_DIR:=%s\n" % target_dir)
1949 writemakefilefooter(file, filename)
1952 def writeimagesettings(image):
1953 """Write Makefile.settings to seperate the settings
1954 from the actual makefile creation."""
1957 global global_options_by_order
1959 filename = os.path.join(image.gettargetdir(), "Makefile.settings")
1960 print "Creating", filename
1961 file = safe_open(filename, 'w+')
1962 writemakefileheader(file, filename)
1963 file.write("TOP:=%s\n" % (treetop))
1964 file.write("TARGET_DIR:=%s\n" % (image.gettargetdir()))
1967 for o in global_exported_options:
1969 for o in image.exported_options:
1970 if (not o in exported):
1973 file.write("export %s:=" % o.name)
1974 if (hasvalue(o.name, image)):
1975 file.write("%s" % getformated(o.name, image))
1978 file.write("export VARIABLES :=\n")
1980 file.write("export VARIABLES += %s\n" % o.name)
1982 writemakefilefooter(file,filename)
1985 # write the romimage makefile
1986 # let's try the Makefile
1987 # first, dump all the -D stuff
1989 def writeimagemakefile(image):
1990 makefilepath = os.path.join(image.gettargetdir(), "Makefile")
1991 print "Creating", makefilepath
1992 file = safe_open(makefilepath, 'w+')
1993 writemakefileheader(file, makefilepath)
1996 file.write("\nall: coreboot.rom\n\n")
1997 file.write(".PHONY: all\n\n")
1998 #file.write("include cpuflags\n")
1999 # Putting "include cpuflags" in the Makefile has the problem that the
2000 # cpuflags file would be generated _after_ we want to include it.
2001 # Instead, let make do the work of computing CPUFLAGS:
2002 file.write("# Get the value of TOP, VARIABLES, and several other variables.\n")
2003 file.write("include Makefile.settings\n\n")
2004 file.write("# Function to create an item like -Di586 or -DCONFIG_MAX_CPUS='1' or -Ui686\n")
2005 file.write("D_item = $(if $(subst undefined,,$(origin $1)),-D$1$(if $($1),='$($1)',),-U$1)\n\n")
2006 file.write("# Compute the value of CPUFLAGS here during make's first pass.\n")
2007 file.write("CPUFLAGS := $(foreach _var_,$(VARIABLES),$(call D_item,$(_var_)))\n\n")
2009 for i in image.getuserdefines():
2010 file.write("%s\n" %i)
2013 # print out all the object dependencies
2014 file.write("\n# object dependencies (objectrules:)\n")
2015 file.write("INIT-OBJECTS :=\n")
2016 file.write("OBJECTS :=\n")
2017 file.write("DRIVER :=\n")
2018 file.write("\nSOURCES :=\n")
2019 for irule, init in image.getinitobjectrules().items():
2022 file.write("INIT-OBJECTS += %s\n" % (i_name))
2023 file.write("SOURCES += %s\n" % (i_source))
2025 for objrule, obj in image.getobjectrules().items():
2028 file.write("OBJECTS += %s\n" % (obj_name))
2029 file.write("SOURCES += %s\n" % (obj_source))
2032 file.write("OBJECTS += static.o\n")
2033 file.write("SOURCES += static.c\n")
2035 for driverrule, driver in image.getdriverrules().items():
2036 obj_name = driver[0]
2037 obj_source = driver[1]
2038 file.write("DRIVER += %s\n" % (obj_name))
2039 file.write("SOURCES += %s\n" % (obj_source))
2041 # Print out all ldscript.ld dependencies.
2042 file.write("\n# ldscript.ld dependencies:\n")
2043 file.write("LDSUBSCRIPTS-1 := \n" )
2044 for script in image.getldscripts():
2045 file.write("LDSUBSCRIPTS-1 += %s\n" % topify(script))
2047 # Print out the dependencies for crt0_includes.h
2048 file.write("\n# Dependencies for crt0_includes.h\n")
2049 file.write("CRT0_INCLUDES:=\n")
2050 for inc in image.getinitincludes():
2051 if (local_path.match(inc)):
2052 file.write("CRT0_INCLUDES += %s\n" % inc)
2054 file.write("CRT0_INCLUDES += $(TOP)/src/%s\n" % inc)
2056 # Print out the user defines.
2057 file.write("\n# userdefines:\n")
2059 # Print out the base rules.
2060 # Need to have a rule that counts on 'all'.
2061 file.write("\n# mainrulelist:")
2063 # Print out any user rules.
2064 file.write("\n# From makerule or docipl commands:\n")
2066 file.write("\n# initobjectrules:\n")
2067 for irule, init in image.getinitobjectrules().items():
2068 source = topify(init[1])
2071 # for .S, .o depends on .s
2072 file.write("%s: %s.s\n" % (init[0], init[3]))
2073 file.write("\t$(CC) -c $(CPU_OPT) -o $@ $<\n")
2074 # and .s depends on .S
2075 file.write("%s.s: %s\n" % (init[3], source))
2076 # Note: next 2 lines are ONE output line!
2077 file.write("\t$(CPP) $(CPPFLAGS) $< ")
2078 file.write(">$@.new && mv $@.new $@\n")
2080 file.write("%s: %s\n" % (init[0], source))
2081 file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
2083 file.write("\n# objectrules:\n")
2084 for objrule, obj in image.getobjectrules().items():
2085 source = topify(obj[1])
2088 # for .S, .o depends on .s
2089 file.write("%s: %s.s\n" % (obj[0], obj[3]))
2090 file.write("\t$(CC) -c $(CPU_OPT) -o $@ $<\n")
2091 # and .s depends on .S
2092 file.write("%s.s: %s\n" % (obj[3], source))
2093 # Note: next 2 lines are ONE output line!
2094 file.write("\t$(CPP) $(CPPFLAGS) $< ")
2095 file.write(">$@.new && mv $@.new $@\n")
2097 file.write("%s: %s\n" % (obj[0], source))
2098 file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
2099 #file.write("%s\n" % objrule[2])
2101 for driverrule, driver in image.getdriverrules().items():
2102 source = topify(driver[1])
2103 file.write("%s: %s\n" % (driver[0], source))
2104 file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
2105 #file.write("%s\n" % objrule[2])
2107 # special rule for chip_target.c
2108 file.write("static.o: static.c\n")
2109 file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
2111 # Print out the rules that will make cause the files
2112 # generated by NLBConfig.py to be remade if any dependencies change.
2114 file.write("\n# Remember the automatically generated files\n")
2115 file.write("GENERATED:=\n")
2116 for genfile in ['Makefile',
2119 'corebootDoc.config' ]:
2120 file.write("GENERATED += %s\n" % genfile)
2121 file.write("GENERATED += %s\n" % image.getincludefilename())
2123 keys = global_options_by_order
2125 file.write("\necho:\n")
2127 file.write("\t@echo %s='$(%s)'\n"% (key,key))
2129 for i, m in image.getmakerules().items():
2130 file.write("%s: " %i)
2131 for i in m.dependency:
2132 file.write("%s " % i)
2135 file.write("\t%s\n" % i)
2136 writemakefilefooter(file, makefilepath)
2140 def writemakefile(path):
2141 makefilepath = os.path.join(path, "Makefile")
2142 print "Creating", makefilepath
2143 file = safe_open(makefilepath, 'w+')
2144 writemakefileheader(file, makefilepath)
2147 file.write("\nall:")
2149 file.write(" %s" % i.name)
2151 file.write("include Makefile.settings\n\n")
2152 for i, o in romimages.items():
2153 file.write("%s/coreboot.rom:\n" % o.getname())
2154 file.write("\tif (cd %s; \\\n" % o.getname())
2155 file.write("\t\t$(MAKE) coreboot.rom)\\\n")
2156 file.write("\tthen true; else exit 1; fi;\n\n")
2157 file.write("clean: ")
2158 for i in romimages.keys():
2159 file.write(" %s-clean" % i)
2160 file.write(" base-clean")
2162 for i, o in romimages.items():
2163 file.write("%s-clean:\n" % o.getname())
2164 file.write("\t(cd %s; $(MAKE) clean)\n\n" % o.getname())
2165 file.write("base-clean:\n")
2166 file.write("\trm -f romcc*\n\n")
2169 file.write("%s:" % i.name)
2171 file.write(" %s/coreboot.rom " % j)
2173 file.write("\t cat ")
2175 file.write(" %s/coreboot.rom " % j)
2176 file.write("> %s\n\n" %i.name)
2179 file.write(".PHONY: all clean")
2180 for i in romimages.keys():
2181 file.write(" %s-clean" % i)
2182 for i, o in romimages.items():
2183 file.write(" %s/coreboot.rom" % o.getname())
2186 writemakefilefooter(file, makefilepath)
2189 def writeinitincludes(image):
2190 global include_pattern
2191 filepath = os.path.join(image.gettargetdir(), image.getincludefilename())
2192 print "Creating", filepath
2193 outfile = safe_open(filepath, 'w+')
2194 if (image.newformat()):
2195 infile = safe_open(image.getinitfile(), 'r')
2197 line = infile.readline()
2199 p = include_pattern.match(line)
2201 for i in image.getinitincludes():
2202 inc = image.getinitinclude(i)
2203 if (inc.getstring() == p.group(1)):
2204 outfile.write("#include \"%s\"\n" % inc.getpath())
2207 line = infile.readline()
2211 for i in image.getinitincludes():
2212 outfile.write("#include <%s>\n" % i)
2215 def writeldoptions(image):
2216 """Write ldoptions file."""
2217 filename = os.path.join(image.gettargetdir(), "ldoptions")
2218 print "Creating", filename
2219 file = safe_open(filename, 'w+')
2220 for o in global_exported_options:
2221 if (hasvalue(o.name, image) and IsInt(getoption(o.name, image))):
2222 file.write("%s = %s;\n" % (o.name, getformated(o.name, image)))
2223 for o in image.exported_options:
2224 if (not o in global_exported_options and hasvalue(o.name, image) and IsInt(getoption(o.name, image))):
2225 file.write("%s = %s;\n" % (o.name, getformated(o.name, image)))
2228 def dumptree(part, lvl):
2229 debug.info(debug.dumptree, "DUMPTREE ME is")
2231 # dump the siblings -- actually are there any? not sure
2233 debug.info(debug.dumptree, "DUMPTREE SIBLINGS are")
2234 kid = part.next_sibling
2237 kid = kid.next_sibling
2239 debug.info(debug.dumptree, "DUMPTREE KIDS are")
2240 #for kid in part.children:
2242 dumptree(part.children, lvl+1)
2243 kid = part.next_sibling
2246 dumptree(kid.children, lvl + 1)
2247 kid = kid.next_sibling
2248 debug.info(debug.dumptree, "DONE DUMPTREE")
2250 def writecode(image):
2251 filename = os.path.join(img_dir, "static.c")
2252 print "Creating", filename
2253 file = safe_open(filename, 'w+')
2254 file.write("#include <device/device.h>\n")
2255 file.write("#include <device/pci.h>\n")
2256 for path in image.getconfigincludes().values():
2257 file.write("#include \"%s\"\n" % path)
2258 gencode(image.getroot(), file, 0)
2259 gencode(image.getroot(), file, 1)
2262 def gencode(part, file, pass_num):
2263 debug.info(debug.gencode, "GENCODE ME is")
2264 part.gencode(file, pass_num)
2265 # dump the siblings -- actually are there any? not sure
2266 debug.info(debug.gencode, "GENCODE SIBLINGS are")
2267 kid = part.next_sibling
2269 kid.gencode(file, pass_num)
2270 kid = kid.next_sibling
2271 # now dump the children
2272 debug.info(debug.gencode, "GENCODE KIDS are")
2274 gencode(part.children, file, pass_num)
2275 kid = part.next_sibling
2278 gencode(kid.children, file, pass_num)
2279 kid = kid.next_sibling
2280 debug.info(debug.gencode, "DONE GENCODE")
2283 """Add any run-time checks to verify that parsing the configuration
2286 for image in romimages.values():
2287 print("Verifying ROMIMAGE %s" % image.name)
2288 if (image.newformat() and image.getinitfile() == ''):
2289 fatal("An init file must be specified")
2290 for op in image.exported_options:
2291 if (getoptionvalue(op.name, op, image) == 0 and getoptionvalue(op.name, op, 0) == 0):
2292 warning("Exported option %s has no value (check Options.lb)" % op.name);
2293 print("Verifing global options")
2294 for op in global_exported_options:
2295 if (getoptionvalue(op.name, op, 0) == 0):
2296 notice("Exported option %s has no value (check Options.lb)" % op.name);
2298 #=============================================================================
2300 #=============================================================================
2301 if __name__=='__main__':
2302 from sys import argv
2304 fatal("Args: <file> <path to coreboot>")
2306 top_config_file = os.path.abspath(sys.argv[1])
2308 treetop = os.path.abspath(sys.argv[2])
2310 # Now read in the customizing script...
2312 fp = safe_open(argv[1], 'r')
2313 if (not parse('board', fp.read())):
2314 fatal("Could not parse file")
2319 # no longer need to check if an options has been used
2322 for image_name, image in romimages.items():
2323 if (debug.level(debug.dumptree)):
2324 debug.info(debug.dumptree, "DEVICE TREE:")
2325 dumptree(image.getroot(), 0)
2327 img_dir = image.gettargetdir()
2328 if not os.path.isdir(img_dir):
2329 print "Creating directory %s" % img_dir
2330 os.makedirs(img_dir)
2332 if (debug.level(debug.dump)):
2333 for i in image.getinitincludes():
2334 debug.info(debug.dump, "crt0include file %s" % i)
2335 for i in image.getdriverrules().keys():
2336 debug.info(debug.dump, "driver file %s" % i)
2337 for i in image.getldscripts():
2338 debug.info(debug.dump, "ldscript file %s" % i)
2339 for i, m in image.getmakerules().items():
2340 debug.info(debug.dump, " makerule %s dep %s act %s" % (i, m.dependency, m.actions))
2343 writeimagesettings(image)
2344 writeinitincludes(image)
2345 writeimagemakefile(image)
2346 writeldoptions(image)
2348 writemakefilesettings(target_dir)
2349 writemakefile(target_dir)