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)
98 def __init__(self, *level):
101 def setdebug(self, *level):
104 def level(self, level):
105 return level in self.__level
107 def info(self, level, str):
108 if level in self.__level:
112 debug = debug_info(debug_info.dumptree)
113 debug = debug_info(debug_info.object)
115 # -----------------------------------------------------------------------------
117 # -----------------------------------------------------------------------------
120 """Used to keep track of our current location while parsing
121 configuration files"""
123 def __init__(self, file, line, command):
126 self.command = command
127 def next_line(self, command):
128 self.line = self.line + 1
129 self.command = command
131 return "%s:%d" % (self.file, self.line)
142 s = s + '\n' + p.at()
146 return self.stack.tos().file
149 return self.stack.tos().line
152 return self.stack.tos().command
154 def push(self, file):
155 self.stack.push(self.__place(os.path.normpath(file), 0, ""))
160 def next_line(self, command):
161 self.stack.tos().next_line(command)
164 return self.stack.tos().at()
168 """Print error message"""
171 print "===> ERROR: %s" % string
175 """Print error message and exit"""
180 """Print warning message"""
182 warnings = warnings + 1
183 print "===> WARNING: %s" % string
186 """Print notice message"""
187 #print "===> NOTE: %s" % string
190 """Exit parser if an error has been encountered"""
194 def safe_open(file, mode):
196 return open(file, mode)
198 fatal("Could not open file \"%s\"" % file)
200 # -----------------------------------------------------------------------------
202 # -----------------------------------------------------------------------------
205 """A rom image is the ultimate goal of coreboot"""
206 def __init__ (self, name):
207 # name of this rom image
210 # set by 'arch' directive
213 # set by 'payload' directive
216 # set by 'init' directive
219 # make rules added by 'makerule' directive
220 self.makebaserules = {}
222 # object files added by 'object' directive
223 self.objectrules = {}
225 # init object files added by 'initobject' directive
226 self.initobjectrules = {}
228 # driver files added by 'driver' directive
229 self.driverrules = {}
231 # smm object files added by 'smmobject' directive
232 self.smmobjectrules = {}
234 # loader scripts added by 'ldscript' directive
237 # user defines added by 'makedefine' directive
238 self.userdefines = []
240 # files to be included in crt0.S
241 self.initincludes = {}
243 # as above, but order is preserved
244 self.initincludesorder = []
246 # transitional flag to support old crtinclude format
247 self.useinitincludes = 0
249 # instance counter for parts
250 self.partinstance = 0
252 # chip config files included by the 'config' directive
253 self.configincludes = {}
258 # name of target directory specified by 'target' directive
261 # option values used in rom image
265 self.exported_options = []
276 def setarch(self, arch):
279 def setpayload(self, payload):
280 self.payload = payload
282 def setinitfile(self, initfile):
283 self.initfile = initfile
285 def getinitfile(self):
288 def addmakerule(self, id):
289 o = getdict(self.makebaserules, id)
291 warning("rule %s previously defined" % id)
293 setdict(self.makebaserules, id, o)
295 def getmakerules(self):
296 return self.makebaserules
298 def getmakerule(self, id):
299 o = getdict(self.makebaserules, id)
302 fatal("No such make rule \"%s\"" % id)
304 def addmakeaction(self, id, str):
305 o = getdict(self.makebaserules, id)
310 fatal("No such rule \"%s\" for addmakeaction" % id)
312 def addmakedepend(self, id, str):
313 o = getdict(self.makebaserules, id)
318 fatal("No such rule \"%s\" for addmakedepend" % id)
320 # this is called with an an object name.
321 # the easiest thing to do is add this object to the current
323 # such kludgery. If the name starts with '.' then make the
324 # dependency be on ./thing.x gag me.
325 def addobjectdriver(self, dict, object_name):
327 suffix = object_name[-2:]
330 base = object_name[:-2]
331 type = object_name[-1:]
332 if (object_name[0] == '.'):
333 source = base + suffix
337 rel_base = re.sub(treetop, "", os.path.join(dirstack.tos(), base))
338 source = "$(TOP)/" + rel_base + suffix
339 if (rel_base[0] == '/'):
340 rel_base = re.sub("^/", "", rel_base)
341 object = rel_base + '.o'
343 debug.info(debug.object, "add object %s source %s" % (object, source))
344 l = getdict(dict, rel_base)
346 warning("object/driver %s previously defined" % rel_base)
347 setdict(dict, rel_base, [object, source, type, rel_base])
349 def addinitobjectrule(self, name):
350 self.addobjectdriver(self.initobjectrules, name)
352 def addobjectrule(self, name):
353 self.addobjectdriver(self.objectrules, name)
355 def adddriverrule(self, name):
356 self.addobjectdriver(self.driverrules, name)
358 def addsmmobjectrule(self, name):
359 self.addobjectdriver(self.smmobjectrules, name)
361 def getinitobjectrules(self):
362 return self.initobjectrules
364 def getinitobjectrule(self, name):
365 o = getdict(self.initobjectrules, name)
368 fatal("No such init object rule \"%s\"" % name)
370 def getobjectrules(self):
371 return self.objectrules
373 def getobjectrule(self, name):
374 o = getdict(self.objectrules, name)
377 fatal("No such object rule \"%s\"" % name)
379 def getdriverrules(self):
380 return self.driverrules
382 def getdriverrule(self, name):
383 o = getdict(self.driverrules, name)
386 fatal("No such driver rule \"%s\"" % name)
388 def getsmmobjectrules(self):
389 return self.smmobjectrules
391 def getsmmobjectrule(self, name):
392 o = getdict(self.smmobjectrules, name)
395 fatal("No such smm object rule \"%s\"" % name)
397 def addldscript(self, path):
398 self.ldscripts.append(path)
400 def getldscripts(self):
401 return self.ldscripts
403 def adduserdefine(self, str):
404 self.userdefines.append(str)
406 def getuserdefines(self):
407 return self.userdefines
409 def addinitinclude(self, str, path):
411 self.useinitincludes = 1
413 debug.info(debug.object, "ADDCRT0: %s -> %s" % (str, path))
414 o = getdict(self.initincludes, path)
416 warning("init include for %s previously defined" % path)
417 o = initinclude(str, path)
418 setdict(self.initincludes, path, o)
419 self.initincludesorder.append(path)
421 def getinitincludes(self):
422 return self.initincludesorder
424 def getinitinclude(self, path):
425 o = getdict(self.initincludes, path)
428 fatal("No such init include \"%s\"" % path)
430 def addconfiginclude(self, part, path):
431 setdict(self.configincludes, part, path)
433 def getconfigincludes(self):
434 return self.configincludes
436 def getincludefilename(self):
437 if (self.useinitincludes):
440 return "crt0_includes.h"
443 return self.useinitincludes
446 return self.partinstance
448 def newpartinstance(self):
449 i = self.partinstance
450 self.partinstance = self.partinstance + 1
453 def setroot(self, part):
459 def settargetdir(self, path):
460 self.targetdir = path
462 def gettargetdir(self):
463 return self.targetdir
466 """A buildrom statement"""
467 def __init__ (self, filename, size, roms):
473 return len(self.roms)
475 def __getitem__(self,i):
479 """include file for initialization code"""
480 def __init__ (self, str, path):
491 """Rule to be included in Makefile"""
492 def __init__ (self, target):
497 def addaction(self, action):
498 self.actions.append(action)
500 def adddependency(self, dependency):
501 self.dependency.append(dependency)
506 def gdependency(self):
507 return self.dependency
513 """Configuration option"""
514 def __init__ (self, name):
515 self.name = name # name of option
516 self.loc = 0 # current location
517 self.used = 0 # option has been used
519 self.comment = '' # description of option
520 self.exportable = 0 # option is able to be exported
521 self.format = '%s' # option print format
522 self.write = [] # parts that can set this option
527 def setcomment(self, comment, loc):
528 if (self.comment != ''):
529 print "%s: " % self.name
530 print "Attempt to modify comment at %s" % loc
532 self.comment = comment
534 def setexportable(self):
537 def setnoexport(self):
540 def setformat(self, fmt):
547 if (self.exportable):
551 def setwrite(self, part):
552 self.write.append(part)
554 def isexportable(self):
555 return self.exportable
557 def iswritable(self, part):
558 return (part in self.write)
561 """Value of a configuration option. The option has a default
562 value which can be changed at any time. Once an option has been
563 set the default value is no longer used."""
564 def __init__(self, name, prev):
569 self.value = prev.value
573 def setvalue(self, value):
574 if ((self.set & 2) == 2):
575 warning("Changing option %s" % self.name)
580 def setdefault(self, value):
581 if ((self.set & 1) == 1):
582 notice("Changing default value of %s" % self.name)
584 if ((self.set & 2) == 0):
592 return (self.set & 2) == 2
596 """A configuration part"""
597 def __init__ (self, image, dir, parent, part, type_name, instance_name, chip_or_device):
598 debug.info(debug.object, "partobj dir %s parent %s part %s" \
599 % (dir, parent, part))
601 # romimage that is configuring this part
604 # links for static device tree
606 self.prev_sibling = 0
607 self.next_sibling = 0
610 self.chip_or_device = chip_or_device
612 # list of init code files
615 # initializers for static device tree
616 self.registercode = {}
621 # type name of this part
622 self.type_name = type_name
624 # object files needed to build this part
627 # directory containg part files
630 # instance number, used to distinguish anonymous
631 # instances of this part
632 self.instance = image.newpartinstance()
633 debug.info(debug.object, "INSTANCE %d" % self.instance)
635 # Options used by this part
636 self.uses_options = {}
638 # Name of chip config file (0 if not needed)
641 # Flag to indicate that we have generated type
642 # definitions for this part (only want to do it once)
648 # Resources of the device
652 # Enabled state of the device
655 # Flag if I am a dumplicate device
658 # If no instance name is supplied then generate
660 if (instance_name == 0):
661 self.instance_name = self.type_name + \
662 "_dev%d" % self.instance
663 self.chipinfo_name = "%s_info_%d" \
664 % (self.type_name, self.instance)
666 self.instance_name = instance_name
667 self.chipinfo_name = "%s_info_%d" % (self.instance_name, self.instance)
669 # Link this part into the device list
670 if (self.chip_or_device == 'device'):
671 if (image.last_device):
672 image.last_device.next_device = self
673 self.prev_device = image.last_device
674 image.last_device = self
676 # Link this part into the tree
677 if (parent and (part != 'arch')):
678 debug.info(debug.gencode, "add to parent")
680 # add current child as my sibling,
682 if (parent.children):
683 debug.info(debug.gencode, "add %s (%d) as sibling" % (parent.children.dir, parent.children.instance))
684 youngest = parent.children
685 while(youngest.next_sibling):
686 youngest = youngest.next_sibling
687 youngest.next_sibling = self
688 self.prev_sibling = youngest
690 parent.children = self
696 return "%s: %s" % (self.part, self.type)
698 return self.chip_or_device
700 def readable_name(self):
702 name = "%s_%d" % (self.type_name, self.instance)
703 if (self.chip_or_device == 'chip'):
704 name = "%s %s %s" % (name, self.part, self.dir)
706 name = "%s %s" % (name, self.path)
709 def graph_name(self):
710 name = "{ {_dev%d|" % self.instance
712 name = "%s%s" % (name, self.part)
714 name = "%s%s" % (name, self.chip_or_device)
716 name = "%s}|%s}" % (name, self.type_name)
718 name = "%s}|%s}" % (name, self.parent.type_name)
721 def dumpme(self, lvl):
722 """Dump information about this part for debugging"""
723 print "%d: %s" % (lvl, self.readable_name())
724 print "%d: part %s" % (lvl, self.part)
725 print "%d: instance %d" % (lvl, self.instance)
726 print "%d: chip_or_device %s" % (lvl, self.chip_or_device)
727 print "%d: dir %s" % (lvl,self.dir)
728 print "%d: type_name %s" % (lvl,self.type_name)
729 print "%d: parent: %s" % (lvl, self.parent.readable_name())
731 print "%d: child %s" % (lvl, self.children.readable_name())
732 if (self.next_sibling):
733 print "%d: siblings %s" % (lvl, self.next_sibling.readable_name())
734 print "%d: initcode " % lvl
735 for i in self.initcode:
737 print "%d: registercode " % lvl
738 for f, v in self.registercode.items():
739 print "\t%s = %s" % (f, v)
742 def firstchilddevice(self):
743 """Find the first device in the children link."""
746 if (kid.chip_or_device == 'device'):
752 def firstparentdevice(self):
753 """Find the first device in the parent link."""
755 while (parent and (parent.parent != parent) and (parent.chip_or_device != 'device')):
756 parent = parent.parent
757 if ((parent.parent != parent) and (parent.chip_or_device != 'device')):
759 while(parent and (parent.dup == 1)):
760 parent = parent.prev_sibling
762 fatal("Device %s has no device parent; this is a config file error" % self.readable_name())
765 def firstparentdevicelink(self):
766 """Find the first device in the parent link and record which link it is."""
769 while (parent and (parent.parent != parent) and (parent.chip_or_device != 'device')):
770 parent = parent.parent
771 if ((parent.parent != parent) and (parent.chip_or_device != 'device')):
773 while(parent and (parent.dup == 1)):
774 parent = parent.prev_sibling
777 fatal("Device %s has no device parent; this is a config file error" % self.readable_name())
781 def firstparentchip(self):
782 """Find the first chip in the parent link."""
785 if ((parent.parent == parent) or (parent.chip_or_device == 'chip')):
788 parent = parent.parent
789 fatal("Device %s has no chip parent; this is a config file error" % self.readable_name())
791 def firstsiblingdevice(self):
792 """Find the first device in the sibling link."""
793 sibling = self.next_sibling
794 while(sibling and (sibling.path == self.path)):
795 sibling = sibling.next_sibling
796 if ((not sibling) and (self.parent.chip_or_device == 'chip')):
797 sibling = self.parent.next_sibling
799 if (sibling.chip_or_device == 'device'):
802 sibling = sibling.children
805 def gencode(self, file, pass_num):
806 """Generate static initalizer code for this part. Two passes
807 are used - the first generates type information, and the second
808 generates instance information"""
810 if (self.chip_or_device == 'chip'):
814 file.write("struct device %s;\n" \
815 % self.instance_name)
817 file.write("struct device dev_root;\n")
819 # This is pass the second, which is pass number 1
820 # this is really just a case statement ...
822 if (self.chip_or_device == 'chip'):
823 if (self.chipconfig):
824 debug.info(debug.gencode, "gencode: chipconfig(%d)" % \
826 file.write("struct %s_config %s" % (self.type_name ,\
828 if (self.registercode):
829 file.write("\t= {\n")
830 for f, v in self.registercode.items():
831 file.write( "\t.%s = %s,\n" % (f, v))
837 if (self.instance == 0):
838 self.instance_name = "dev_root"
839 file.write("struct device **last_dev_p = &%s.next;\n" % (self.image.last_device.instance_name))
840 file.write("struct device dev_root = {\n")
841 file.write("\t.ops = &default_dev_ops_root,\n")
842 file.write("\t.bus = &dev_root.link[0],\n")
843 file.write("\t.path = { .type = DEVICE_PATH_ROOT },\n")
844 file.write("\t.enabled = 1,\n\t.links = 1,\n")
845 file.write("\t.on_mainboard = 1,\n")
846 file.write("\t.link = {\n\t\t[0] = {\n")
847 file.write("\t\t\t.dev=&dev_root,\n\t\t\t.link = 0,\n")
848 file.write("\t\t\t.children = &%s,\n" % self.firstchilddevice().instance_name)
849 file.write("\t\t},\n")
851 if (self.chipconfig):
852 file.write("\t.chip_ops = &%s_ops,\n" % self.type_name)
853 file.write("\t.chip_info = &%s_info_%s,\n" % (self.type_name, self.instance))
854 file.write("\t.next = &%s,\n" % self.firstchilddevice().instance_name)
858 # Don't print duplicate devices, just print their children
862 file.write("struct device %s = {\n" % self.instance_name)
863 file.write("\t.ops = 0,\n")
864 file.write("\t.bus = &%s.link[%d],\n" % \
865 (self.firstparentdevice().instance_name, \
866 self.firstparentdevicelink()))
867 file.write("\t.path = {%s},\n" % self.path)
868 file.write("\t.enabled = %d,\n" % self.enabled)
869 file.write("\t.on_mainboard = 1,\n")
871 file.write("\t.resources = %d,\n" % self.resources)
872 file.write("\t.resource = {%s\n\t },\n" % self.resource)
873 file.write("\t.link = {\n");
876 while(bus and (bus.path == self.path)):
877 child = bus.firstchilddevice()
878 if (child or (bus != self) or (bus.next_sibling and (bus.next_sibling.path == self.path))):
879 file.write("\t\t[%d] = {\n" % links)
880 file.write("\t\t\t.link = %d,\n" % links)
881 file.write("\t\t\t.dev = &%s,\n" % self.instance_name)
883 file.write("\t\t\t.children = &%s,\n" %child.instance_name)
884 file.write("\t\t},\n")
887 bus = bus.next_sibling
891 file.write("\t.links = %d,\n" % (links))
892 sibling = self.firstsiblingdevice();
894 file.write("\t.sibling = &%s,\n" % sibling.instance_name)
895 chip = self.firstparentchip()
896 if (chip and chip.chipconfig):
897 file.write("\t.chip_ops = &%s_ops,\n" % chip.type_name)
898 file.write("\t.chip_info = &%s_info_%s,\n" % (chip.type_name, chip.instance))
899 if (self.next_device):
900 file.write("\t.next=&%s\n" % self.next_device.instance_name)
904 def addinit(self, code):
905 """Add init file to this part"""
906 self.initcode.append(code)
908 def addconfig(self, path):
909 """Add chip config file to this part"""
910 self.chipconfig = os.path.join(self.dir, path)
911 self.image.addconfiginclude(self.type_name, self.chipconfig)
913 def addregister(self, field, value):
914 """Register static initialization information"""
915 if (self.chip_or_device != 'chip'):
916 fatal("Only chips can have register values")
917 field = dequote(field)
918 value = dequote(value)
919 setdict(self.registercode, field, value)
921 def set_enabled(self, enabled):
922 self.enabled = enabled
924 def start_resources(self):
928 def end_resources(self):
929 self.resource = "%s" % (self.resource)
931 def add_resource(self, type, index, value):
932 """ Add a resource to a device """
933 self.resource = "%s\n\t\t{ .flags=%s, .index=0x%x, .base=0x%x}," % (self.resource, type, index, value)
934 self.resources = self.resources + 1
936 def set_path(self, path):
938 if (self.prev_sibling and (self.prev_sibling.path == self.path)):
940 if (self.prev_device):
941 self.prev_device.next_device = self.next_device
942 if (self.next_device):
943 self.next_device.prev_device = self.prev_device
944 if (self.image.last_device == self):
945 self.image.last_device = self.prev_device
949 def addpcipath(self, slot, function):
950 """ Add a relative pci style path from our parent to this device """
951 if ((slot < 0) or (slot > 0x1f)):
952 fatal("Invalid device id")
953 if ((function < 0) or (function > 7)):
954 fatal("Invalid pci function %s" % function )
955 self.set_path(".type=DEVICE_PATH_PCI,{.pci={ .devfn = PCI_DEVFN(0x%x,%d)}}" % (slot, function))
957 def addpnppath(self, port, device):
958 """ Add a relative path to a pnp device hanging off our parent """
959 if ((port < 0) or (port > 65536)):
960 fatal("Invalid port")
961 if ((device < 0) or (device > 0xffff)):
962 fatal("Invalid device")
963 self.set_path(".type=DEVICE_PATH_PNP,{.pnp={ .port = 0x%x, .device = 0x%x }}" % (port, device))
965 def addi2cpath(self, device):
966 """ Add a relative path to a i2c device hanging off our parent """
967 if ((device < 0) or (device > 0x7f)):
968 fatal("Invalid device")
969 self.set_path(".type=DEVICE_PATH_I2C,{.i2c={ .device = 0x%x }}" % (device))
971 def addapicpath(self, apic_id):
972 """ Add a relative path to a cpu device hanging off our parent """
973 if ((apic_id < 0) or (apic_id > 255)):
974 fatal("Invalid device")
975 self.set_path(".type=DEVICE_PATH_APIC,{.apic={ .apic_id = 0x%x }}" % (apic_id))
977 def addpci_domainpath(self, pci_domain):
978 """ Add a pci_domain number to a chip """
979 if ((pci_domain < 0) or (pci_domain > 0xffff)):
980 fatal("Invalid pci_domain: 0x%x is out of the range 0 to 0xffff" % pci_domain)
981 self.set_path(".type=DEVICE_PATH_PCI_DOMAIN,{.pci_domain={ .domain = 0x%x }}" % (pci_domain))
983 def addapic_clusterpath(self, cluster):
984 """ Add an apic cluster to a chip """
985 if ((cluster < 0) or (cluster > 15)):
986 fatal("Invalid apic cluster: %d is out of the range 0 to ff" % cluster)
987 self.set_path(".type=DEVICE_PATH_APIC_CLUSTER,{.apic_cluster={ .cluster = 0x%x }}" % (cluster))
989 def addcpupath(self, cpu_id):
990 """ Add a relative path to a cpu device hanging off our parent """
991 if ((cpu_id < 0) or (cpu_id > 255)):
992 fatal("Invalid device")
993 self.set_path(".type=DEVICE_PATH_CPU,{.cpu={ .id = 0x%x }}" % (cpu_id))
996 def addcpu_buspath(self, id):
997 """ Add a cpu_bus to a chip """
998 if ((id < 0) or (id > 255)):
999 fatal("Invalid device")
1000 self.set_path(".type=DEVICE_PATH_CPU_BUS,{.cpu_bus={ .id = 0x%x }}" % (id))
1002 def usesoption(self, name):
1003 """Declare option that can be used by this part"""
1004 global global_options
1005 o = getdict(global_options, name)
1007 fatal("can't use undefined option %s" % name)
1008 o1 = getdict(self.uses_options, name)
1011 setdict(self.uses_options, name, o)
1012 exportoption(o, self.image.exported_options)
1014 # -----------------------------------------------------------------------------
1016 # -----------------------------------------------------------------------------
1018 def getdict(dict, name):
1019 if name not in dict.keys():
1020 debug.info(debug.dict, "Undefined: %s" % name)
1022 v = dict.get(name, 0)
1023 debug.info(debug.dict, "getdict %s returning %s" % (name, v))
1026 def setdict(dict, name, value):
1027 debug.info(debug.dict, "setdict sets %s to %s" % (name, value))
1028 if name in dict.keys():
1029 print "Duplicate in dict: %s" % name
1033 # to create an option, it has to not exist.
1034 # When an option value is fetched, the fact that it was used is
1036 # Legal things to do:
1037 # set a default value, then set a real value before the option is used.
1038 # set a value, try to set a default, default silently fails.
1040 # use the value, then try to set the value
1042 def newoption(name):
1043 global global_options, global_options_by_order
1044 o = getdict(global_options, name)
1046 fatal("option %s already defined" % name)
1048 setdict(global_options, name, o)
1049 global_options_by_order.append(name)
1051 def newoptionvalue(name, image):
1052 g = getdict(global_option_values, name)
1053 v = option_value(name, g)
1055 setdict(image.getvalues(), name, v)
1057 setdict(global_option_values, name, v)
1060 def getoptionvalue(name, op, image):
1061 global global_option_values
1062 #print "getoptionvalue name %s op %s image %s\n" % (name, op,image)
1064 # we want to debug config files, not the config tool, so no:
1066 fatal("Option %s undefined (missing use command?)" % name)
1068 v = getdict(image.getvalues(), name)
1070 v = getdict(global_option_values, name)
1073 def getoption(name, image):
1074 """option must be declared before being used in a part
1075 if we're not processing a part, then we must
1076 be at the top level where all options are available"""
1078 global global_uses_options, alloptions, curimage
1080 #print "getoption: name %s image %s alloptions %s curimage %s\n\n" % (name, image, alloptions, curimage)
1081 curpart = partstack.tos()
1083 o = getdict(global_options, name)
1085 o = getdict(curpart.uses_options, name)
1087 print "curpart.uses_options is %s\n" % curpart.uses_options
1089 o = getdict(global_uses_options, name)
1090 v = getoptionvalue(name, o, image)
1092 v = getoptionvalue(name, o, 0)
1094 fatal("No value for option %s" % name)
1096 if (not (type(val) is types.StringType)):
1098 if (val == '' or val[0] != '{'):
1102 val = parse('delexpr', val)
1107 def setoption(name, value, imp):
1108 """Set an option from within a configuration file. Normally this
1109 is only permitted in the target (top level) configuration file.
1110 If 'imp' is true, then set an option implicitly (e.g. 'arch'
1111 and 'mainboard' statements). Implicit options can be set anywhere
1112 the statements are legal, but also performs an implicit 'uses'
1115 global loc, global_options, global_option_values, curimage
1117 curpart = partstack.tos()
1118 if (not imp and curpart):
1119 fatal("Options may only be set in target configuration file")
1123 o = getdict(curpart.uses_options, name)
1125 o = getdict(global_uses_options, name)
1127 fatal("Attempt to set nonexistent option %s (missing USES?)" % name)
1128 v = getoptionvalue(name, o, curimage)
1130 v = newoptionvalue(name, curimage)
1133 def exportoption(op, exported_options):
1134 if (not op.isexportable()):
1136 if (not op in exported_options):
1137 exported_options.append(op)
1139 def setdefault(name, value, isdef):
1140 """Set the default value of an option from within a configuration
1141 file. This is permitted from any configuration file, but will
1142 result in a warning if the default is set more than once.
1143 If 'isdef' is set, we're defining the option in Options.lb so
1144 there is no need for 'uses'."""
1146 global loc, global_options, curimage
1149 o = getdict(global_options, name)
1154 curpart = partstack.tos()
1156 o = getdict(curpart.uses_options, name)
1158 o = getdict(global_uses_options, name)
1160 fatal("Attempt to set default for nonexistent option %s (missing USES?)" % name)
1163 v = getoptionvalue(name, o, image)
1165 v = newoptionvalue(name, image)
1168 def setnodefault(name):
1169 global loc, global_options
1170 o = getdict(global_options, name)
1173 v = getdict(global_option_values, name)
1175 warning("removing default for %s" % name)
1176 del global_option_values[name]
1178 def setcomment(name, value):
1179 global loc, global_options
1180 o = getdict(global_options, name)
1182 fatal("setcomment: %s not here" % name)
1183 o.setcomment(value, loc)
1185 def setexported(name):
1186 global global_options
1187 o = getdict(global_options, name)
1189 fatal("setexported: %s not here" % name)
1191 global_exported_options.append(o)
1193 def setnoexport(name):
1194 global global_options
1195 o = getdict(global_options, name)
1197 fatal("setnoexport: %s not here" % name)
1199 if (o in global_exported_options):
1200 global_exported_options.remove(o)
1202 def setexportable(name):
1203 global global_options
1204 o = getdict(global_options, name)
1206 fatal("setexportable: %s not here" % name)
1209 def setformat(name, fmt):
1210 global global_options
1211 o = getdict(global_options, name)
1213 fatal("setformat: %s not here" % name)
1216 def getformated(name, image):
1217 global global_options, global_option_values
1218 o = getdict(global_options, name)
1219 v = getoption(name, image)
1223 def setwrite(name, part):
1224 global global_options
1225 o = getdict(global_options, name)
1227 fatal("setwrite: %s not here" % name)
1230 def hasvalue(name, image):
1231 global global_options
1232 o = getdict(global_options, name)
1237 v = getdict(image.getvalues(), name)
1239 v = getdict(global_option_values, name)
1242 def isset(name, part):
1243 global global_uses_options, global_option_values, curimage
1245 o = getdict(part.uses_options, name)
1247 o = getdict(global_uses_options, name)
1252 v = getdict(curimage.getvalues(), name)
1254 v = getdict(global_option_values, name)
1255 return (v != 0 and v.isset())
1257 def usesoption(name):
1258 global global_options, global_uses_options
1259 curpart = partstack.tos()
1261 curpart.usesoption(name)
1263 o = getdict(global_options, name)
1265 fatal("Can't use undefined option %s" % name)
1266 o1 = getdict(global_uses_options, name)
1269 setdict(global_uses_options, name, o)
1270 exportoption(o, global_exported_options)
1272 def validdef(name, defval):
1273 global global_options
1274 o = getdict(global_options, name)
1276 fatal("validdef: %s not here" % name)
1277 if ((defval & 1) != 1):
1278 fatal("Must specify default value for option %s" % name)
1279 if ((defval & 2) != 2):
1280 fatal("Must specify export for option %s" % name)
1281 if ((defval & 4) != 4):
1282 fatal("Must specify comment for option %s" % name)
1284 def loadoptions(path, file, rule):
1285 file = os.path.join('src', path, file)
1286 optionsfile = os.path.join(treetop, file)
1287 fp = safe_open(optionsfile, 'r')
1289 if (not parse(rule, fp.read())):
1290 fatal("Could not parse file")
1294 global curimage, dirstack
1295 if (path[0] == '/'):
1296 curimage.setinitfile(treetop + '/src/' + path)
1298 curimage.setinitfile(dirstack.tos() + '/' + path)
1299 print "Adding init file: %s" % path
1301 def addconfig(path):
1303 curpart = partstack.tos()
1304 curpart.addconfig(path)
1306 def addregister(field, value):
1308 curpart = partstack.tos()
1309 curpart.addregister(field, value)
1311 def addcrt0include(path):
1312 """we do the crt0include as a dictionary, so that if needed we
1313 can trace who added what when. Also it makes the keys
1316 curimage.addinitinclude(0, path)
1318 def addinitinclude(str, path):
1320 curimage.addinitinclude(dequote(str), path)
1322 def addldscript(path):
1323 global curimage, dirstack
1324 curdir = dirstack.tos()
1325 if (path[0] == '/'):
1326 fullpath = treetop + '/src/' + path
1328 fullpath = curdir + '/' + path
1329 debug.info(debug.statement, "fullpath :%s: curdir :%s: path :%s:" % (fullpath, curdir, path))
1330 curimage.addldscript(fullpath)
1334 curimage.setpayload(path)
1335 adduserdefine("PAYLOAD:=%s"%path)
1337 def startromimage(name):
1338 global romimages, curimage, target_dir, target_name
1339 curpart = partstack.tos()
1340 print "Configuring ROMIMAGE %s Curimage %s" % (name, curimage)
1341 print "Curpart is %s\n" % curpart
1342 o = getdict(romimages, name)
1344 fatal("romimage %s previously defined" % name)
1345 curimage = romimage(name)
1346 curimage.settargetdir(os.path.join(target_dir, name))
1347 #o = partobj(curimage, target_dir, 0, 'board', target_name)
1348 #curimage.setroot(o)
1349 setdict(romimages, name, curimage)
1350 dodir('/config', 'Config.lb')
1355 print "End ROMIMAGE"
1359 def mainboardsetup(path):
1360 global full_mainboard_path, mainboard_path
1361 mainboard_path = os.path.join('mainboard', path)
1362 loadoptions(mainboard_path, 'Options.lb', 'mainboardvariables')
1363 full_mainboard_path = os.path.join(treetop, 'src', 'mainboard', path)
1364 vendor = re.sub("/.*", "", path)
1365 part_number = re.sub("[^/]*/", "", path)
1366 setdefault('MAINBOARD', full_mainboard_path, 0)
1367 setdefault('MAINBOARD_VENDOR', vendor, 0)
1368 setdefault('MAINBOARD_PART_NUMBER', part_number, 0)
1371 global curimage, dirstack, partstack
1373 partdir = mainboard_path
1374 srcdir = os.path.join(treetop, 'src')
1375 fulldir = os.path.join(srcdir, partdir)
1376 type_name = flatten_name(partdir)
1377 newpart = partobj(curimage, fulldir, partstack.tos(), 'mainboard', \
1378 'mainboard', 0, 'chip')
1379 #print "Configuring PART %s" % (type)
1380 partstack.push(newpart)
1381 #print " new PART tos is now %s\n" %partstack.tos().info()
1382 dirstack.push(fulldir)
1383 loadoptions(mainboard_path, 'Options.lb', 'mainboardvariables')
1384 # special case for 'cpu' parts.
1385 # we could add a new function too, but this is rather trivial.
1386 # if the part is a cpu, and we haven't seen it before,
1387 # arrange to source the directory /cpu/'type'
1388 doconfigfile(srcdir, partdir, file, 'cfgfile')
1389 curimage.setroot(partstack.tos())
1392 def addbuildrom(filename, size, roms):
1394 print "Build ROM size %d" % size
1395 b = buildrom(filename, size, roms)
1398 def addinitobject(object_name):
1400 curimage.addinitobjectrule(object_name)
1402 def addobject(object_name):
1404 curimage.addobjectrule(object_name)
1406 def adddriver(driver_name):
1408 curimage.adddriverrule(driver_name)
1410 def addsmmobject(object_name):
1412 curimage.addsmmobjectrule(object_name)
1415 global target_dir, target_name
1416 print "Configuring TARGET %s" % name
1418 target_dir = os.path.join(os.path.dirname(loc.file()), name)
1419 if not os.path.isdir(target_dir):
1420 print "Creating directory %s" % target_dir
1421 os.makedirs(target_dir)
1422 print "Will place Makefile, crt0.S, etc. in %s" % target_dir
1427 if (cpu_type and (cpu_type != path)):
1428 fatal("Two different CPU types: %s and %s" % (cpu_type, path))
1429 srcdir = "/cpu/%s" % path
1430 dodir(srcdir, "Config.lb")
1433 def devicepart(type):
1434 global curimage, dirstack, partstack
1435 newpart = partobj(curimage, 0, partstack.tos(), type, \
1437 #print "Configuring PART %s" % (type)
1438 partstack.push(newpart)
1439 #print " new PART tos is now %s\n" %partstack.tos().info()
1440 # just push TOS, so that we can pop later.
1441 dirstack.push(dirstack.tos())
1443 def part(type, path, file, name):
1444 global curimage, dirstack, partstack
1445 partdir = os.path.join(type, path)
1446 srcdir = os.path.join(treetop, 'src')
1447 fulldir = os.path.join(srcdir, partdir)
1448 type_name = flatten_name(partdir)
1449 newpart = partobj(curimage, fulldir, partstack.tos(), type, \
1450 type_name, name, 'chip')
1451 #print "Configuring PART %s, path %s" % (type, path)
1452 partstack.push(newpart)
1453 #print " new PART tos is now %s\n" %partstack.tos().info()
1454 dirstack.push(fulldir)
1455 # special case for 'cpu' parts.
1456 # we could add a new function too, but this is rather trivial.
1457 # if the part is a cpu, and we haven't seen it before,
1458 # arrange to source the directory /cpu/'type'
1462 doconfigfile(srcdir, partdir, file, 'cfgfile')
1465 global dirstack, partstack
1466 curpart = partstack.tos()
1468 fatal("Trying to pop non-existent part")
1469 #print "End PART %s" % curpart.part
1470 # Warn if options are used without being set in this part
1471 for op in curpart.uses_options.keys():
1472 if (not isset(op, curpart)):
1473 notice("Option %s using default value %s" % (op, getformated(op, curpart.image)))
1474 oldpart = partstack.pop()
1476 #print "partstack.pop, TOS is now %s\n" % oldpart.info()
1478 def dodir(path, file):
1479 """dodir is like part but there is no new part"""
1481 # if the first char is '/', it is relative to treetop,
1482 # else relative to curdir
1483 # os.path.join screws up if the name starts with '/', sigh.
1484 print "Configuring DIR %s" % os.path.join(path, file)
1485 if (path[0] == '/'):
1486 fullpath = os.path.join(treetop, 'src')
1487 path = re.sub('^/*', '', path)
1489 fullpath = dirstack.tos()
1490 debug.info(debug.statement, "DODIR: path %s, fullpath %s" % (path, fullpath))
1491 dirstack.push(os.path.join(fullpath, path))
1492 doconfigfile(fullpath, path, file, 'cfgfile')
1497 return getoption(name, curimage)
1501 curimage.addmakerule(id)
1503 def adduserdefine(str):
1505 curimage.adduserdefine(str)
1507 def addaction(id, str):
1509 curimage.addmakeaction(id, str)
1511 def adddep(id, str):
1513 curimage.addmakedepend(id, str)
1515 def setarch(my_arch):
1516 """arch is 'different' ... darn it."""
1518 print "SETTING ARCH %s\n" % my_arch
1519 curimage.setarch(my_arch)
1520 setdefault('ARCH', my_arch, 1)
1521 part('arch', my_arch, 'Config.lb', 0)
1523 def doconfigfile(path, confdir, file, rule):
1524 rname = os.path.join(confdir, file)
1526 fullpath = os.path.join(path, rname)
1527 fp = safe_open(fullpath, 'r')
1528 if (not parse(rule, fp.read())):
1529 fatal("Could not parse file")
1533 #=============================================================================
1535 #=============================================================================
1536 def ternary(val, yes, no):
1537 debug.info(debug.statement, "ternary %s" % expr)
1538 debug.info(debug.statement, "expr %s a %d yes %d no %d"% (expr, a, yes, no))
1540 debug.info(debug.statement, "Ternary returns %d" % yes)
1543 debug.info(debug.statement, "Ternary returns %d" % no)
1547 """atoi is in the python library, but not strtol? Weird!"""
1548 return eval('int(%s)' % name)
1551 """ Is the given string an integer?"""
1559 a = re.sub("^\"", "", str)
1560 a = re.sub("\"$", "", a)
1561 # highly un-intuitive, need four \!
1562 a = re.sub("\\\\\"", "\"", a)
1565 def flatten_name(str):
1566 a = re.sub("[/-]", "_", str)
1570 """If the first part of <path> matches treetop, replace
1571 that part with $(TOP)"""
1572 if path[0:len(treetop)] == treetop:
1573 path = path[len(treetop):len(path)]
1574 if (path[0:1] == "/"):
1575 path = path[1:len(path)]
1576 path = "$(TOP)/" + path
1580 # to make if work without 2 passses, we use an old hack from SIMD, the
1581 # context bit. If the bit is 1, then ops get done, otherwise
1582 # ops don't get done. From the top level, context is always
1583 # 1. In an if, context depends on eval of the if condition
1589 # less general tokens should come first, otherwise they get matched
1591 token ACTION: 'action'
1592 token ADDACTION: 'addaction'
1593 token ALWAYS: 'always'
1595 token BUILDROM: 'buildrom'
1596 token COMMENT: 'comment'
1597 token CONFIG: 'config'
1599 token CPU_BUS: 'cpu_bus'
1601 token DEFAULT: 'default'
1602 token DEFINE: 'define'
1603 token DEPENDS: 'depends'
1604 token DEVICE: 'device'
1606 token DRIVER: 'driver'
1612 token EXPORT: 'export'
1613 token FORMAT: 'format'
1616 token INITOBJECT: 'initobject'
1617 token INITINCLUDE: 'initinclude'
1620 token LDSCRIPT: 'ldscript'
1621 token LOADOPTIONS: 'loadoptions'
1622 token MAINBOARD: 'mainboard'
1623 token MAINBOARDINIT: 'mainboardinit'
1624 token MAKEDEFINE: 'makedefine'
1625 token MAKERULE: 'makerule'
1627 token NEVER: 'never'
1629 token NORTHBRIDGE: 'northbridge'
1630 token OBJECT: 'object'
1631 token OPTION: 'option'
1632 token PAYLOAD: 'payload'
1634 token PRINT: 'print'
1635 token REGISTER: 'register'
1636 token ROMIMAGE: 'romimage'
1637 token SMMOBJECT: 'smmobject'
1638 token SOUTHBRIDGE: 'southbridge'
1639 token SUPERIO: 'superio'
1640 token TARGET: 'target'
1643 token WRITE: 'write'
1645 token HEX_NUM: '[0-9a-fA-F]+'
1646 token HEX_PREFIX: '0x'
1647 # Why is path separate? Because paths to resources have to at least
1648 # have a slash, we thinks
1649 token PATH: r'[-a-zA-Z0-9_.][-a-zA-Z0-9/_.]+[-a-zA-Z0-9_.]+'
1650 # Dir's on the other hand are abitrary
1651 # this may all be stupid.
1652 token RULE: r'[-a-zA-Z0-9_$()./]+[-a-zA-Z0-9_ $()./]+[-a-zA-Z0-9_$()./]+'
1653 token DIRPATH: r'[-a-zA-Z0-9_$()./]+'
1654 token ID: r'[a-zA-Z_.]+[a-zA-Z0-9_.]*'
1655 token DELEXPR: r'{([^}]+|\\.)*}'
1656 token STR: r'"([^\\"]+|\\.)*"'
1657 token RAWTEXT: r'.*'
1664 token APIC_CLUSTER: 'apic_cluster'
1666 token CPU_BUS: 'cpu_bus'
1667 token PCI_DOMAIN: 'pci_domain'
1670 rule expr: logical {{ l = logical }}
1671 ( "&&" logical {{ l = l and logical }}
1672 | "||" logical {{ l = l or logical }}
1675 rule logical: factor {{ n = factor }}
1676 ( "[+]" factor {{ n = n+factor }}
1677 | "-" factor {{ n = n-factor }}
1680 rule factor: term {{ v = term }}
1681 ( "[*]" term {{ v = v*term }}
1682 | "/" term {{ v = v/term }}
1683 | "<<" term {{ v = v << term }}
1684 | ">=" term {{ v = (v < term)}}
1687 # A term is a number, variable, or an expression surrounded by parentheses
1688 rule term: NUM {{ return long(NUM, 10) }}
1689 | HEX_PREFIX HEX_NUM {{ return long(HEX_NUM, 16) }}
1690 | ID {{ return lookup(ID) }}
1691 | unop {{ return unop }}
1692 | "\\(" expr "\\)" {{ return expr }}
1694 rule unop: "!" expr {{ return not(expr) }}
1696 rule partend<<C>>: (stmt<<C>>)* END {{ if (C): partpop()}}
1698 # This is needed because the legacy cpu command could not distinguish
1699 # between cpu vendors. It should just be PATH, but getting this change
1700 # into the source tree will be tricky...
1701 # DO NOT USE ID AS IT MAY GO AWAY IN THE FUTURE
1702 rule partid: ID {{ return ID }}
1703 | PATH {{ return PATH }}
1705 # rule parttype: NORTHBRIDGE {{ return 'northbridge' }}
1706 # | SUPERIO {{ return 'superio' }}
1707 # | PMC {{ return 'pmc' }}
1708 # | SOUTHBRIDGE {{ return 'southbridge' }}
1709 # | CPU {{ return 'cpu' }}
1710 # | CHIP {{ return '' }}
1712 rule parttype: CHIP {{ return '' }}
1714 rule partdef<<C>>: {{ name = 0 }}
1716 [ STR {{ name = dequote(STR) }}
1717 ] {{ if (C): part(parttype, partid, 'Config.lb', name) }}
1720 rule arch<<C>>: ARCH ID {{ if (C): setarch(ID) }}
1723 rule mainboardinit<<C>>:
1724 MAINBOARDINIT DIRPATH {{ if (C): addcrt0include(DIRPATH)}}
1726 rule initinclude<<C>>:
1729 DIRPATH {{ if (C): addinitinclude(STR, DIRPATH)}}
1731 rule initobject<<C>>:
1732 INITOBJECT DIRPATH {{ if (C): addinitobject(DIRPATH)}}
1734 rule object<<C>>: OBJECT DIRPATH {{ if (C): addobject(DIRPATH)}}
1736 rule driver<<C>>: DRIVER DIRPATH {{ if (C): adddriver(DIRPATH)}}
1738 rule smmobject<<C>>:
1739 SMMOBJECT DIRPATH {{ if (C): addsmmobject(DIRPATH)}}
1742 rule dir<<C>>: DIR DIRPATH {{ if (C): dodir(DIRPATH, 'Config.lb') }}
1744 rule default<<C>>: DEFAULT ID EQ value {{ if (C): setdefault(ID, value, 0) }}
1746 rule ldscript<<C>>: LDSCRIPT DIRPATH {{ if (C): addldscript(DIRPATH) }}
1748 rule iif<<C>>: IF ID {{ c = lookup(ID) }}
1750 [ ELSE (stmt<<C and not c>>)* ]
1753 rule makerule<<C>>: MAKERULE RULE {{ if (C): addrule(RULE) }}
1754 ( DEPENDS STR {{ if (C): adddep(RULE, STR) }}
1755 | ACTION STR {{ if (C): addaction(RULE, STR) }}
1759 rule makedefine<<C>>:
1760 MAKEDEFINE RAWTEXT {{ if (C): adduserdefine(RAWTEXT) }}
1762 rule addaction<<C>>:
1763 ADDACTION ID STR {{ if (C): addaction(ID, STR) }}
1765 rule init<<C>>: INIT DIRPATH {{ if (C): addinit(DIRPATH) }}
1767 rule field: STR {{ return STR }}
1769 rule register<<C>>: REGISTER field '=' STR {{ if (C): addregister(field, STR) }}
1771 rule enable<<C>>: {{ val = 1 }}
1774 ) {{ if(C): partstack.tos().set_enabled(val) }}
1776 rule resource<<C>>: {{ type = "" }}
1777 ( IO {{ type = "IORESOURCE_FIXED | IORESOURCE_ASSIGNED | IORESOURCE_IO" }}
1778 | MEM {{ type = "IORESOURCE_FIXED | IORESOURCE_ASSIGNED | IORESOURCE_MEM" }}
1779 | IRQ {{ type = "IORESOURCE_FIXED | IORESOURCE_ASSIGNED | IORESOURCE_IRQ" }}
1780 | DRQ {{ type = "IORESOURCE_FIXED | IORESOURCE_ASSIGNED | IORESOURCE_DRQ" }}
1782 term '=' {{ index = term }}
1783 term {{ value = term }}
1784 {{ if (C): partstack.tos().add_resource(type, index, value) }}
1787 rule resources<<C>>: {{ if (C): partstack.tos().start_resources() }}
1789 {{ if (C): partstack.tos().end_resources() }}
1792 rule pci<<C>>: PCI {{ if (C): devicepart('pci') }}
1794 HEX_NUM {{ slot = int(HEX_NUM,16) }}
1795 '.' HEX_NUM {{ function = int(HEX_NUM, 16) }}
1796 {{ if (C): partstack.tos().addpcipath(slot, function) }}
1797 rule pci_domain<<C>>:
1798 PCI_DOMAIN {{ if (C): devicepart('pci_domain') }}
1799 HEX_NUM {{ pci_domain = int(HEX_NUM, 16) }}
1800 {{ if (C): partstack.tos().addpci_domainpath(pci_domain) }}
1802 rule pnp<<C>>: PNP {{ if (C): devicepart('pnp') }}
1803 HEX_NUM {{ port = int(HEX_NUM,16) }}
1804 '.' HEX_NUM {{ device = int(HEX_NUM, 16) }}
1805 {{ if (C): partstack.tos().addpnppath(port, device) }}
1807 rule i2c<<C>>: I2C {{ if (C): devicepart('i2c') }}
1808 HEX_NUM {{ device = int(HEX_NUM, 16) }}
1809 {{ if (C): partstack.tos().addi2cpath(device) }}
1811 rule apic<<C>>: APIC {{ if (C): devicepart('apic') }}
1812 HEX_NUM {{ apic_id = int(HEX_NUM, 16) }}
1813 {{ if (C): partstack.tos().addapicpath(apic_id) }}
1815 rule apic_cluster<<C>>: APIC_CLUSTER {{ if (C): devicepart('apic_cluster') }}
1816 HEX_NUM {{ cluster = int(HEX_NUM, 16) }}
1817 {{ if (C): partstack.tos().addapic_clusterpath(cluster) }}
1819 rule cpu<<C>>: CPU {{ if (C): devicepart('cpu') }}
1820 HEX_NUM {{ id = int(HEX_NUM, 16) }}
1821 {{ if (C): partstack.tos().addcpupath(id) }}
1823 rule cpu_bus<<C>>: CPU_BUS {{ if (C): devicepart('cpu_bus') }}
1824 HEX_NUM {{ id = int(HEX_NUM, 16) }}
1825 {{ if (C): partstack.tos().addcpu_buspath(id) }}
1828 pci<<C>> {{ return pci }}
1829 | pci_domain<<C>> {{ return pci_domain }}
1830 | pnp<<C>> {{ return pnp }}
1831 | i2c<<C>> {{ return i2c }}
1832 | apic<<C>> {{ return apic }}
1833 | apic_cluster<<C>> {{ return apic_cluster }}
1834 | cpu<<C>> {{ return cpu }}
1835 | cpu_bus<<C>> {{ return cpu_bus }}
1837 rule prtval: expr {{ return str(expr) }}
1838 | STR {{ return STR }}
1840 rule prtlist: prtval {{ el = "%(" + prtval }}
1841 ( "," prtval {{ el = el + "," + prtval }}
1842 )* {{ return el + ")" }}
1844 rule prtstmt<<C>>: PRINT STR {{ val = STR }}
1845 [ "," prtlist {{ val = val + prtlist }}
1846 ] {{ if (C): print eval(val) }}
1848 rule config<<C>>: CONFIG PATH {{ if (C): addconfig(PATH) }}
1850 rule device<<C>>: DEVICE dev_path<<C>>
1855 rule stmt<<C>>: arch<<C>> {{ return arch}}
1856 | addaction<<C>> {{ return addaction }}
1857 | config<<C>> {{ return config}}
1858 | default<<C>> {{ return default}}
1859 | dir<<C>> {{ return dir}}
1860 | driver<<C>> {{ return driver }}
1861 | iif<<C>> {{ return iif }}
1862 | init<<C>> {{ return init }}
1863 | initinclude<<C>> {{ return initinclude }}
1864 | initobject<<C>> {{ return initobject }}
1865 | ldscript<<C>> {{ return ldscript}}
1866 | mainboardinit<<C>> {{ return mainboardinit }}
1867 | makedefine<<C>> {{ return makedefine }}
1868 | makerule<<C>> {{ return makerule }}
1869 | object<<C>> {{ return object }}
1870 | option<<C>> {{ return option }}
1871 | partdef<<C>> {{ return partdef }}
1872 | prtstmt<<C>> {{ return prtstmt }}
1873 | register<<C>> {{ return register }}
1874 | device<<C>> {{ return device }}
1875 | smmobject<<C>> {{ return smmobject }}
1877 # ENTRY for parsing Config.lb file
1878 rule cfgfile: (uses<<1>>)*
1882 rule cfgfile: (uses<<1>>)*
1886 rule usesid<<C>>: ID {{ if (C): usesoption(ID) }}
1888 rule uses<<C>>: USES (usesid<<C>>)+
1890 rule mainboardvariables: (uses<<1>>)*
1895 rule value: STR {{ return dequote(STR) }}
1896 | expr {{ return expr }}
1897 | DELEXPR {{ return DELEXPR }}
1899 rule option<<C>>: OPTION ID EQ value {{ if (C): setoption(ID, value, 0) }}
1901 rule opif<<C>>: IF ID {{ c = lookup(ID) }}
1902 (opstmt<<C and c>>)*
1903 [ ELSE (opstmt<<C and not c>>)* ]
1906 rule opstmt<<C>>: option<<C>>
1910 rule payload<<C>>: PAYLOAD DIRPATH {{ if (C): payload(DIRPATH) }}
1913 MAINBOARD PATH {{ mainboardsetup(PATH) }}
1915 rule romif<<C>>: IF ID {{ c = lookup(ID) }}
1916 (romstmt<<C and c>>)*
1917 [ ELSE (romstmt<<C and not c>>)* ]
1920 rule romstmt<<C>>: romif<<C>>
1924 rule romimage: ROMIMAGE STR {{ startromimage(dequote(STR)) }}
1926 END {{ endromimage() }}
1928 rule roms: STR {{ s = '[' + STR }}
1929 ( STR {{ s = s + "," + STR }}
1930 )* {{ return eval(s + ']') }}
1932 rule buildrom: BUILDROM DIRPATH expr roms {{ addbuildrom(DIRPATH, expr, roms) }}
1934 rule romstmts: romimage
1938 # ENTRY for parsing root part
1939 rule board: {{ loadoptions("config", "Options.lb", "options") }}
1940 TARGET DIRPATH {{ target(DIRPATH) }}
1945 # ENTRY for parsing a delayed value
1946 rule delexpr: "{" expr "}" EOF {{ return expr }}
1948 rule wrstr<<ID>>: STR {{ setwrite(ID, dequote(STR)) }}
1950 rule defstmts<<ID>>: {{ d = 0 }}
1952 ( value {{ setdefault(ID, value, 1) }}
1953 | NONE {{ setnodefault(ID) }}
1955 | FORMAT STR {{ setformat(ID, dequote(STR)) }}
1957 ( ALWAYS {{ setexported(ID) }}
1958 | USED {{ setexportable(ID) }}
1959 | NEVER {{ setnoexport(ID) }}
1961 | COMMENT STR {{ setcomment(ID, dequote(STR)); d = d | 4 }}
1962 | WRITE (wrstr<<ID>>)+
1965 rule define: DEFINE ID {{ newoption(ID) }}
1966 defstmts<<ID>> END {{ validdef(ID, defstmts) }}
1968 # ENTRY for parsing Options.lb file
1969 rule options: (define)* EOF {{ return 1 }}
1972 #=============================================================================
1974 #=============================================================================
1975 def writemakefileheader(file, fname):
1976 file.write("# File: %s is autogenerated\n" % fname)
1978 def writemakefilefooter(file, fname):
1979 file.write("\n\n%s: %s %s\n"
1980 % (os.path.basename(fname), os.path.abspath(sys.argv[0]), top_config_file))
1981 file.write("\t(cd %s ; export PYTHONPATH=%s/util/newconfig ; python %s %s %s)\n\n"
1982 % (os.getcwd(), treetop, sys.argv[0], sys.argv[1], sys.argv[2]))
1984 def writemakefilesettings(path):
1985 """ Write Makefile.settings to seperate the settings
1986 from the actual makefile creation."""
1988 global treetop, target_dir
1990 filename = os.path.join(path, "Makefile.settings")
1991 print "Creating", filename
1992 file = safe_open(filename, 'w+')
1993 writemakefileheader(file, filename)
1994 file.write("TOP:=%s\n" % (treetop))
1995 file.write("TARGET_DIR:=%s\n" % target_dir)
1996 writemakefilefooter(file, filename)
1999 def writeimagesettings(image):
2000 """Write Makefile.settings to seperate the settings
2001 from the actual makefile creation."""
2004 global global_options_by_order
2006 filename = os.path.join(image.gettargetdir(), "Makefile.settings")
2007 print "Creating", filename
2008 file = safe_open(filename, 'w+')
2009 writemakefileheader(file, filename)
2010 file.write("TOP:=%s\n" % (treetop))
2011 file.write("TARGET_DIR:=%s\n" % (image.gettargetdir()))
2014 for o in global_exported_options:
2016 for o in image.exported_options:
2017 if (not o in exported):
2020 file.write("export %s:=" % o.name)
2021 if (hasvalue(o.name, image)):
2022 file.write("%s" % getformated(o.name, image))
2025 file.write("export VARIABLES :=\n")
2027 file.write("export VARIABLES += %s\n" % o.name)
2029 writemakefilefooter(file,filename)
2032 # write the romimage makefile
2033 # let's try the Makefile
2034 # first, dump all the -D stuff
2036 def writeimagemakefile(image):
2037 makefilepath = os.path.join(image.gettargetdir(), "Makefile")
2038 print "Creating", makefilepath
2039 file = safe_open(makefilepath, 'w+')
2040 writemakefileheader(file, makefilepath)
2043 file.write("\nall: coreboot.rom\n\n")
2044 file.write(".PHONY: all\n\n")
2045 #file.write("include cpuflags\n")
2046 # Putting "include cpuflags" in the Makefile has the problem that the
2047 # cpuflags file would be generated _after_ we want to include it.
2048 # Instead, let make do the work of computing CPUFLAGS:
2049 file.write("# Get the value of TOP, VARIABLES, and several other variables.\n")
2050 file.write("include Makefile.settings\n\n")
2051 file.write("# Function to create an item like -Di586 or -DCONFIG_MAX_CPUS='1' or -Ui686\n")
2052 file.write("D_item = $(if $(subst undefined,,$(origin $1)),-D$1$(if $($1),='$($1)',),-U$1)\n\n")
2053 file.write("# Compute the value of CPUFLAGS here during make's first pass.\n")
2054 file.write("CPUFLAGS := $(foreach _var_,$(VARIABLES),$(call D_item,$(_var_)))\n\n")
2056 for i in image.getuserdefines():
2057 file.write("%s\n" %i)
2060 # print out all the object dependencies
2061 file.write("\n# object dependencies (objectrules:)\n")
2062 file.write("INIT-OBJECTS :=\n")
2063 file.write("OBJECTS :=\n")
2064 file.write("DRIVER :=\n")
2065 file.write("\nSOURCES :=\n")
2066 for irule, init in image.getinitobjectrules().items():
2069 file.write("INIT-OBJECTS += %s\n" % (i_name))
2070 file.write("SOURCES += %s\n" % (i_source))
2072 for objrule, obj in image.getobjectrules().items():
2075 file.write("OBJECTS += %s\n" % (obj_name))
2076 file.write("SOURCES += %s\n" % (obj_source))
2078 for srule, smm in image.getsmmobjectrules().items():
2081 file.write("SMM-OBJECTS += %s\n" % (s_name))
2082 file.write("SOURCES += %s\n" % (s_source))
2086 file.write("OBJECTS += static.o\n")
2087 file.write("SOURCES += static.c\n")
2089 for driverrule, driver in image.getdriverrules().items():
2090 obj_name = driver[0]
2091 obj_source = driver[1]
2092 file.write("DRIVER += %s\n" % (obj_name))
2093 file.write("SOURCES += %s\n" % (obj_source))
2095 # Print out all ldscript.ld dependencies.
2096 file.write("\n# ldscript.ld dependencies:\n")
2097 file.write("LDSUBSCRIPTS-1 := \n" )
2098 for script in image.getldscripts():
2099 file.write("LDSUBSCRIPTS-1 += %s\n" % topify(script))
2101 # Print out the dependencies for crt0_includes.h
2102 file.write("\n# Dependencies for crt0_includes.h\n")
2103 file.write("CRT0_INCLUDES:=\n")
2104 for inc in image.getinitincludes():
2105 if (local_path.match(inc)):
2106 file.write("CRT0_INCLUDES += %s\n" % inc)
2108 file.write("CRT0_INCLUDES += $(TOP)/src/%s\n" % inc)
2110 # Print out the user defines.
2111 file.write("\n# userdefines:\n")
2113 # Print out the base rules.
2114 # Need to have a rule that counts on 'all'.
2115 file.write("\n# mainrulelist:")
2117 # Print out any user rules.
2118 file.write("\n# From makerule or docipl commands:\n")
2120 file.write("\n# initobjectrules:\n")
2121 for irule, init in image.getinitobjectrules().items():
2122 source = topify(init[1])
2125 # for .S, .o depends on .s
2126 file.write("%s: %s.s\n" % (init[0], init[3]))
2127 file.write("\t$(CC) -c $(CPU_OPT) -o $@ $<\n")
2128 # and .s depends on .S
2129 file.write("%s.s: %s\n" % (init[3], source))
2130 # Note: next 2 lines are ONE output line!
2131 file.write("\t$(CPP) $(CPPFLAGS) $< ")
2132 file.write(">$@.new && mv $@.new $@\n")
2134 file.write("%s: %s\n" % (init[0], source))
2135 file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
2137 file.write("\n# objectrules:\n")
2138 for objrule, obj in image.getobjectrules().items():
2139 source = topify(obj[1])
2142 # for .S, .o depends on .s
2143 file.write("%s: %s.s\n" % (obj[0], obj[3]))
2144 file.write("\t$(CC) -c $(CPU_OPT) -o $@ $<\n")
2145 # and .s depends on .S
2146 file.write("%s.s: %s\n" % (obj[3], source))
2147 # Note: next 2 lines are ONE output line!
2148 file.write("\t$(CPP) $(CPPFLAGS) $< ")
2149 file.write(">$@.new && mv $@.new $@\n")
2151 file.write("%s: %s\n" % (obj[0], source))
2152 file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
2153 #file.write("%s\n" % objrule[2])
2155 for driverrule, driver in image.getdriverrules().items():
2156 source = topify(driver[1])
2157 file.write("%s: %s\n" % (driver[0], source))
2158 file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
2159 #file.write("%s\n" % objrule[2])
2161 file.write("\n# smmobjectrules:\n")
2162 for irule, smm in image.getsmmobjectrules().items():
2163 source = topify(smm[1])
2166 # for .S, .o depends on .s
2167 file.write("%s: %s.s\n" % (smm[0], smm[3]))
2168 file.write("\t$(CC) -c $(CPU_OPT) -o $@ $<\n")
2169 # and .s depends on .S
2170 file.write("%s.s: %s\n" % (smm[3], source))
2171 # Note: next 2 lines are ONE output line!
2172 file.write("\t$(CPP) $(CPPFLAGS) $< ")
2173 file.write(">$@.new && mv $@.new $@\n")
2175 file.write("%s: %s\n" % (smm[0], source))
2176 file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
2178 # special rule for chip_target.c
2179 file.write("static.o: static.c\n")
2180 file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
2182 # Print out the rules that will make cause the files
2183 # generated by NLBConfig.py to be remade if any dependencies change.
2185 file.write("\n# Remember the automatically generated files\n")
2186 file.write("GENERATED:=\n")
2187 for genfile in ['Makefile',
2190 'corebootDoc.config' ]:
2191 file.write("GENERATED += %s\n" % genfile)
2192 file.write("GENERATED += %s\n" % image.getincludefilename())
2194 keys = global_options_by_order
2196 file.write("\necho:\n")
2198 file.write("\t@echo %s='$(%s)'\n"% (key,key))
2200 for i, m in image.getmakerules().items():
2201 file.write("%s: " %i)
2202 for i in m.dependency:
2203 file.write("%s " % i)
2206 file.write("\t%s\n" % i)
2207 writemakefilefooter(file, makefilepath)
2211 def writemakefile(path):
2212 makefilepath = os.path.join(path, "Makefile")
2213 print "Creating", makefilepath
2214 file = safe_open(makefilepath, 'w+')
2215 writemakefileheader(file, makefilepath)
2218 file.write("\nall:")
2220 file.write(" %s" % i.name)
2222 file.write("include Makefile.settings\n\n")
2223 for i, o in romimages.items():
2224 file.write("%s/coreboot.rom:\n" % o.getname())
2225 file.write("\tif (cd %s; \\\n" % o.getname())
2226 file.write("\t\t$(MAKE) coreboot.rom)\\\n")
2227 file.write("\tthen true; else exit 1; fi;\n\n")
2228 file.write("clean: ")
2229 for i in romimages.keys():
2230 file.write(" %s-clean" % i)
2231 file.write(" base-clean")
2233 for i, o in romimages.items():
2234 file.write("%s-clean:\n" % o.getname())
2235 file.write("\t(cd %s; $(MAKE) clean)\n\n" % o.getname())
2236 file.write("base-clean:\n")
2237 file.write("\trm -f romcc*\n\n")
2240 file.write("%s:" % i.name)
2242 file.write(" %s/coreboot.rom " % j)
2244 file.write("\t cat ")
2246 file.write(" %s/coreboot.rom " % j)
2247 file.write("> %s\n\n" %i.name)
2250 file.write(".PHONY: all clean")
2251 for i in romimages.keys():
2252 file.write(" %s-clean" % i)
2253 for i, o in romimages.items():
2254 file.write(" %s/coreboot.rom" % o.getname())
2257 writemakefilefooter(file, makefilepath)
2260 def writeinitincludes(image):
2261 global include_pattern
2262 filepath = os.path.join(image.gettargetdir(), image.getincludefilename())
2263 print "Creating", filepath
2264 outfile = safe_open(filepath, 'w+')
2265 if (image.newformat()):
2266 infile = safe_open(image.getinitfile(), 'r')
2268 line = infile.readline()
2270 p = include_pattern.match(line)
2272 for i in image.getinitincludes():
2273 inc = image.getinitinclude(i)
2274 if (inc.getstring() == p.group(1)):
2275 outfile.write("#include \"%s\"\n" % inc.getpath())
2278 line = infile.readline()
2282 for i in image.getinitincludes():
2283 outfile.write("#include <%s>\n" % i)
2286 def writeldoptions(image):
2287 """Write ldoptions file."""
2288 filename = os.path.join(image.gettargetdir(), "ldoptions")
2289 print "Creating", filename
2290 file = safe_open(filename, 'w+')
2291 for o in global_exported_options:
2292 if (hasvalue(o.name, image) and IsInt(getoption(o.name, image))):
2293 file.write("%s = %s;\n" % (o.name, getformated(o.name, image)))
2294 for o in image.exported_options:
2295 if (not o in global_exported_options and hasvalue(o.name, image) and IsInt(getoption(o.name, image))):
2296 file.write("%s = %s;\n" % (o.name, getformated(o.name, image)))
2299 def dumptree(part, lvl):
2300 debug.info(debug.dumptree, "DUMPTREE ME is")
2302 # dump the siblings -- actually are there any? not sure
2304 debug.info(debug.dumptree, "DUMPTREE SIBLINGS are")
2305 kid = part.next_sibling
2308 kid = kid.next_sibling
2310 debug.info(debug.dumptree, "DUMPTREE KIDS are")
2311 #for kid in part.children:
2313 dumptree(part.children, lvl+1)
2314 kid = part.next_sibling
2317 dumptree(kid.children, lvl + 1)
2318 kid = kid.next_sibling
2319 debug.info(debug.dumptree, "DONE DUMPTREE")
2321 def writecode(image):
2322 filename = os.path.join(img_dir, "static.c")
2323 print "Creating", filename
2324 file = safe_open(filename, 'w+')
2325 file.write("#include <device/device.h>\n")
2326 file.write("#include <device/pci.h>\n")
2327 for path in image.getconfigincludes().values():
2328 file.write("#include \"%s\"\n" % path)
2329 file.write("\n/* pass 0 */\n")
2330 gencode(image.getroot(), file, 0)
2331 file.write("\n/* pass 1 */\n")
2332 gencode(image.getroot(), file, 1)
2335 def gencode(part, file, pass_num):
2336 debug.info(debug.gencode, "GENCODE ME is")
2337 part.gencode(file, pass_num)
2338 # dump the siblings -- actually are there any? not sure
2339 debug.info(debug.gencode, "GENCODE SIBLINGS are")
2340 kid = part.next_sibling
2342 kid.gencode(file, pass_num)
2343 kid = kid.next_sibling
2344 # now dump the children
2345 debug.info(debug.gencode, "GENCODE KIDS are")
2347 gencode(part.children, file, pass_num)
2348 kid = part.next_sibling
2351 gencode(kid.children, file, pass_num)
2352 kid = kid.next_sibling
2353 debug.info(debug.gencode, "DONE GENCODE")
2355 def writegraph(image):
2356 filename = os.path.join(img_dir, "static.dot")
2357 print "Creating", filename
2358 file = safe_open(filename, 'w+')
2359 file.write("digraph devicetree {\n")
2360 file.write(" rankdir=LR\n")
2361 genranks(image.getroot(), file, 0)
2362 gennodes(image.getroot(), file)
2363 gengraph(image.getroot(), file)
2367 def genranks(part, file, level):
2368 #file.write(" # Level %d\n" % level )
2369 file.write(" { rank = same; \"dev_%s_%d\"" % (part.type_name,part.instance ))
2370 sib = part.next_sibling
2372 file.write("; \"dev_%s_%d\"" % (sib.type_name, sib.instance))
2373 sib = sib.next_sibling
2375 # now dump the children
2377 genranks(part.children, file, level + 1)
2379 kid = part.next_sibling
2382 genranks(kid.children, file, level + 1)
2383 kid = kid.next_sibling
2386 def gennodes(part, file):
2387 file.write(" dev_%s_%d[shape=record, label=\"%s\"];\n" % (part.type_name,part.instance,part.graph_name() ))
2388 sib = part.next_sibling
2390 file.write(" dev_%s_%d[shape=record, label=\"%s\"];\n" % (sib.type_name,sib.instance,sib.graph_name() ))
2391 sib = sib.next_sibling
2392 # now dump the children
2394 gennodes(part.children, file)
2396 kid = part.next_sibling
2399 gennodes(kid.children, file)
2400 kid = kid.next_sibling
2403 def gengraph(part, file):
2404 if (part.parent != part):
2405 file.write(" dev_%s_%d -> dev_%s_%d;\n" % \
2406 (part.parent.type_name, part.parent.instance, \
2407 part.type_name, part.instance ))
2408 sib = part.next_sibling
2410 file.write(" dev_%s_%d -> dev_%s_%d;\n" % \
2411 (sib.parent.type_name, sib.parent.instance, \
2412 sib.type_name, sib.instance ))
2413 sib = sib.next_sibling
2415 kid = part.next_sibling
2418 gengraph(kid.children, file)
2419 kid = kid.next_sibling
2422 gengraph(part.children, file)
2425 """Add any run-time checks to verify that parsing the configuration
2428 for image in romimages.values():
2429 print("Verifying ROMIMAGE %s" % image.name)
2430 if (image.newformat() and image.getinitfile() == ''):
2431 fatal("An init file must be specified")
2432 for op in image.exported_options:
2433 if (getoptionvalue(op.name, op, image) == 0 and getoptionvalue(op.name, op, 0) == 0):
2434 warning("Exported option %s has no value (check Options.lb)" % op.name);
2435 print("Verifing global options")
2436 for op in global_exported_options:
2437 if (getoptionvalue(op.name, op, 0) == 0):
2438 notice("Exported option %s has no value (check Options.lb)" % op.name);
2440 #=============================================================================
2442 #=============================================================================
2443 if __name__=='__main__':
2444 from sys import argv
2446 fatal("Args: <file> <path to coreboot>")
2448 top_config_file = os.path.abspath(sys.argv[1])
2450 treetop = os.path.abspath(sys.argv[2])
2452 # Now read in the customizing script...
2454 fp = safe_open(argv[1], 'r')
2455 if (not parse('board', fp.read())):
2456 fatal("Could not parse file")
2461 # no longer need to check if an options has been used
2464 for image_name, image in romimages.items():
2465 if (debug.level(debug.dumptree)):
2466 debug.info(debug.dumptree, "DEVICE TREE:")
2467 dumptree(image.getroot(), 0)
2469 img_dir = image.gettargetdir()
2470 if not os.path.isdir(img_dir):
2471 print "Creating directory %s" % img_dir
2472 os.makedirs(img_dir)
2474 for objrule, obj in image.getobjectrules().items():
2475 sub_dir = img_dir + '/' + os.path.dirname(obj[0])
2476 if not os.path.isdir(sub_dir):
2477 print "Creating sub directory %s" % sub_dir
2478 os.makedirs(sub_dir)
2480 for driverrule, driver in image.getdriverrules().items():
2481 sub_dir = img_dir + '/' + os.path.dirname(driver[0])
2482 if not os.path.isdir(sub_dir):
2483 print "Creating sub directory %s" % sub_dir
2484 os.makedirs(sub_dir)
2486 for srule, smm in image.getsmmobjectrules().items():
2487 sub_dir = img_dir + '/' + os.path.dirname(smm[0])
2488 if not os.path.isdir(sub_dir):
2489 print "Creating sub directory %s" % sub_dir
2490 os.makedirs(sub_dir)
2492 for irule, init in image.getinitobjectrules().items():
2493 sub_dir = img_dir + '/' + os.path.dirname(init[0])
2494 if not os.path.isdir(sub_dir):
2495 print "Creating sub directory %s" % sub_dir
2496 os.makedirs(sub_dir)
2498 if (debug.level(debug.dump)):
2499 for i in image.getinitincludes():
2500 debug.info(debug.dump, "crt0include file %s" % i)
2501 for i in image.getdriverrules().keys():
2502 debug.info(debug.dump, "driver file %s" % i)
2503 for i in image.getldscripts():
2504 debug.info(debug.dump, "ldscript file %s" % i)
2505 for i, m in image.getmakerules().items():
2506 debug.info(debug.dump, " makerule %s dep %s act %s" % (i, m.dependency, m.actions))
2509 writeimagesettings(image)
2510 writeinitincludes(image)
2511 writeimagemakefile(image)
2512 writeldoptions(image)
2515 writemakefilesettings(target_dir)
2516 writemakefile(target_dir)