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 linuxbios"""
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 'drive' 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 > 0xff)):
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 DIRPATH: r'[-a-zA-Z0-9_$()./]+'
1611 token ID: r'[a-zA-Z_.]+[a-zA-Z0-9_.]*'
1612 token DELEXPR: r'{([^}]+|\\.)*}'
1613 token STR: r'"([^\\"]+|\\.)*"'
1614 token RAWTEXT: r'.*'
1621 token APIC_CLUSTER: 'apic_cluster'
1623 token CPU_BUS: 'cpu_bus'
1624 token PCI_DOMAIN: 'pci_domain'
1627 rule expr: logical {{ l = logical }}
1628 ( "&&" logical {{ l = l and logical }}
1629 | "||" logical {{ l = l or logical }}
1632 rule logical: factor {{ n = factor }}
1633 ( "[+]" factor {{ n = n+factor }}
1634 | "-" factor {{ n = n-factor }}
1637 rule factor: term {{ v = term }}
1638 ( "[*]" term {{ v = v*term }}
1639 | "/" term {{ v = v/term }}
1640 | "<<" term {{ v = v << term }}
1641 | ">=" term {{ v = (v < term)}}
1644 # A term is a number, variable, or an expression surrounded by parentheses
1645 rule term: NUM {{ return long(NUM, 10) }}
1646 | HEX_PREFIX HEX_NUM {{ return long(HEX_NUM, 16) }}
1647 | ID {{ return lookup(ID) }}
1648 | unop {{ return unop }}
1649 | "\\(" expr "\\)" {{ return expr }}
1651 rule unop: "!" expr {{ return not(expr) }}
1653 rule partend<<C>>: (stmt<<C>>)* END {{ if (C): partpop()}}
1655 # This is needed because the legacy cpu command could not distinguish
1656 # between cpu vendors. It should just be PATH, but getting this change
1657 # into the source tree will be tricky...
1658 # DO NOT USE ID AS IT MAY GO AWAY IN THE FUTURE
1659 rule partid: ID {{ return ID }}
1660 | PATH {{ return PATH }}
1662 # rule parttype: NORTHBRIDGE {{ return 'northbridge' }}
1663 # | SUPERIO {{ return 'superio' }}
1664 # | PMC {{ return 'pmc' }}
1665 # | SOUTHBRIDGE {{ return 'southbridge' }}
1666 # | CPU {{ return 'cpu' }}
1667 # | CHIP {{ return '' }}
1669 rule parttype: CHIP {{ return '' }}
1671 rule partdef<<C>>: {{ name = 0 }}
1673 [ STR {{ name = dequote(STR) }}
1674 ] {{ if (C): part(parttype, partid, 'Config.lb', name) }}
1677 rule arch<<C>>: ARCH ID {{ if (C): setarch(ID) }}
1680 rule mainboardinit<<C>>:
1681 MAINBOARDINIT DIRPATH {{ if (C): addcrt0include(DIRPATH)}}
1683 rule initinclude<<C>>:
1686 DIRPATH {{ if (C): addinitinclude(STR, DIRPATH)}}
1688 rule initobject<<C>>:
1689 INITOBJECT DIRPATH {{ if (C): addinitobject(DIRPATH)}}
1691 rule object<<C>>: OBJECT DIRPATH {{ if (C): addobject(DIRPATH)}}
1693 rule driver<<C>>: DRIVER DIRPATH {{ if (C): adddriver(DIRPATH)}}
1695 rule dir<<C>>: DIR DIRPATH {{ if (C): dodir(DIRPATH, 'Config.lb') }}
1697 rule default<<C>>: DEFAULT ID EQ value {{ if (C): setdefault(ID, value, 0) }}
1699 rule ldscript<<C>>: LDSCRIPT DIRPATH {{ if (C): addldscript(DIRPATH) }}
1701 rule iif<<C>>: IF ID {{ c = lookup(ID) }}
1703 [ ELSE (stmt<<C and not c>>)* ]
1706 rule depsacts<<ID, C>>:
1707 ( DEPENDS STR {{ if (C): adddep(ID, STR) }}
1708 | ACTION STR {{ if (C): addaction(ID, STR) }}
1711 rule makerule<<C>>: MAKERULE DIRPATH {{ if (C): addrule(DIRPATH) }}
1712 depsacts<<DIRPATH, C>>
1715 rule makedefine<<C>>:
1716 MAKEDEFINE RAWTEXT {{ if (C): adduserdefine(RAWTEXT) }}
1718 rule addaction<<C>>:
1719 ADDACTION ID STR {{ if (C): addaction(ID, STR) }}
1721 rule init<<C>>: INIT DIRPATH {{ if (C): addinit(DIRPATH) }}
1723 rule field: STR {{ return STR }}
1725 rule register<<C>>: REGISTER field '=' STR {{ if (C): addregister(field, STR) }}
1727 rule enable<<C>>: {{ val = 1 }}
1730 ) {{ if(C): partstack.tos().set_enabled(val) }}
1732 rule resource<<C>>: {{ type = "" }}
1733 ( IO {{ type = "IORESOURCE_FIXED | IORESOURCE_ASSIGNED | IORESOURCE_IO" }}
1734 | MEM {{ type = "IORESOURCE_FIXED | IORESOURCE_ASSIGNED | IORESOURCE_MEM" }}
1735 | IRQ {{ type = "IORESOURCE_FIXED | IORESOURCE_ASSIGNED | IORESOURCE_IRQ" }}
1736 | DRQ {{ type = "IORESOURCE_FIXED | IORESOURCE_ASSIGNED | IORESOURCE_DRQ" }}
1738 term '=' {{ index = term }}
1739 term {{ value = term }}
1740 {{ if (C): partstack.tos().add_resource(type, index, value) }}
1743 rule resources<<C>>: {{ if (C): partstack.tos().start_resources() }}
1745 {{ if (C): partstack.tos().end_resources() }}
1748 rule pci<<C>>: PCI {{ if (C): devicepart('pci') }}
1750 HEX_NUM {{ slot = int(HEX_NUM,16) }}
1751 '.' HEX_NUM {{ function = int(HEX_NUM, 16) }}
1752 {{ if (C): partstack.tos().addpcipath(slot, function) }}
1753 rule pci_domain<<C>>:
1754 PCI_DOMAIN {{ if (C): devicepart('pci_domain') }}
1755 HEX_NUM {{ pci_domain = int(HEX_NUM, 16) }}
1756 {{ if (C): partstack.tos().addpci_domainpath(pci_domain) }}
1758 rule pnp<<C>>: PNP {{ if (C): devicepart('pnp') }}
1759 HEX_NUM {{ port = int(HEX_NUM,16) }}
1760 '.' HEX_NUM {{ device = int(HEX_NUM, 16) }}
1761 {{ if (C): partstack.tos().addpnppath(port, device) }}
1763 rule i2c<<C>>: I2C {{ if (C): devicepart('i2c') }}
1764 HEX_NUM {{ device = int(HEX_NUM, 16) }}
1765 {{ if (C): partstack.tos().addi2cpath(device) }}
1767 rule apic<<C>>: APIC {{ if (C): devicepart('apic') }}
1768 HEX_NUM {{ apic_id = int(HEX_NUM, 16) }}
1769 {{ if (C): partstack.tos().addapicpath(apic_id) }}
1771 rule apic_cluster<<C>>: APIC_CLUSTER {{ if (C): devicepart('apic_cluster') }}
1772 HEX_NUM {{ cluster = int(HEX_NUM, 16) }}
1773 {{ if (C): partstack.tos().addapic_clusterpath(cluster) }}
1775 rule cpu<<C>>: CPU {{ if (C): devicepart('cpu') }}
1776 HEX_NUM {{ id = int(HEX_NUM, 16) }}
1777 {{ if (C): partstack.tos().addcpupath(id) }}
1779 rule cpu_bus<<C>>: CPU_BUS {{ if (C): devicepart('cpu_bus') }}
1780 HEX_NUM {{ id = int(HEX_NUM, 16) }}
1781 {{ if (C): partstack.tos().addcpu_buspath(id) }}
1784 pci<<C>> {{ return pci }}
1785 | pci_domain<<C>> {{ return pci_domain }}
1786 | pnp<<C>> {{ return pnp }}
1787 | i2c<<C>> {{ return i2c }}
1788 | apic<<C>> {{ return apic }}
1789 | apic_cluster<<C>> {{ return apic_cluster }}
1790 | cpu<<C>> {{ return cpu }}
1791 | cpu_bus<<C>> {{ return cpu_bus }}
1793 rule prtval: expr {{ return str(expr) }}
1794 | STR {{ return STR }}
1796 rule prtlist: prtval {{ el = "%(" + prtval }}
1797 ( "," prtval {{ el = el + "," + prtval }}
1798 )* {{ return el + ")" }}
1800 rule prtstmt<<C>>: PRINT STR {{ val = STR }}
1801 [ "," prtlist {{ val = val + prtlist }}
1802 ] {{ if (C): print eval(val) }}
1804 rule config<<C>>: CONFIG PATH {{ if (C): addconfig(PATH) }}
1806 rule device<<C>>: DEVICE dev_path<<C>>
1811 rule stmt<<C>>: arch<<C>> {{ return arch}}
1812 | addaction<<C>> {{ return addaction }}
1813 | config<<C>> {{ return config}}
1814 | default<<C>> {{ return default}}
1815 | dir<<C>> {{ return dir}}
1816 | driver<<C>> {{ return driver }}
1817 | iif<<C>> {{ return iif }}
1818 | init<<C>> {{ return init }}
1819 | initinclude<<C>> {{ return initinclude }}
1820 | initobject<<C>> {{ return initobject }}
1821 | ldscript<<C>> {{ return ldscript}}
1822 | mainboardinit<<C>> {{ return mainboardinit }}
1823 | makedefine<<C>> {{ return makedefine }}
1824 | makerule<<C>> {{ return makerule }}
1825 | object<<C>> {{ return object }}
1826 | option<<C>> {{ return option }}
1827 | partdef<<C>> {{ return partdef }}
1828 | prtstmt<<C>> {{ return prtstmt }}
1829 | register<<C>> {{ return register }}
1830 | device<<C>> {{ return device }}
1832 # ENTRY for parsing Config.lb file
1833 rule cfgfile: (uses<<1>>)*
1837 rule cfgfile: (uses<<1>>)*
1841 rule usesid<<C>>: ID {{ if (C): usesoption(ID) }}
1843 rule uses<<C>>: USES (usesid<<C>>)+
1845 rule mainboardvariables: (uses<<1>>)*
1850 rule value: STR {{ return dequote(STR) }}
1851 | expr {{ return expr }}
1852 | DELEXPR {{ return DELEXPR }}
1854 rule option<<C>>: OPTION ID EQ value {{ if (C): setoption(ID, value, 0) }}
1856 rule opif<<C>>: IF ID {{ c = lookup(ID) }}
1857 (opstmt<<C and c>>)*
1858 [ ELSE (opstmt<<C and not c>>)* ]
1861 rule opstmt<<C>>: option<<C>>
1865 rule payload<<C>>: PAYLOAD DIRPATH {{ if (C): payload(DIRPATH) }}
1868 MAINBOARD PATH {{ mainboardsetup(PATH) }}
1870 rule romif<<C>>: IF ID {{ c = lookup(ID) }}
1871 (romstmt<<C and c>>)*
1872 [ ELSE (romstmt<<C and not c>>)* ]
1875 rule romstmt<<C>>: romif<<C>>
1879 rule romimage: ROMIMAGE STR {{ startromimage(dequote(STR)) }}
1881 END {{ endromimage() }}
1883 rule roms: STR {{ s = '[' + STR }}
1884 ( STR {{ s = s + "," + STR }}
1885 )* {{ return eval(s + ']') }}
1887 rule buildrom: BUILDROM DIRPATH expr roms {{ addbuildrom(DIRPATH, expr, roms) }}
1889 rule romstmts: romimage
1893 # ENTRY for parsing root part
1894 rule board: {{ loadoptions("config", "Options.lb", "options") }}
1895 TARGET DIRPATH {{ target(DIRPATH) }}
1900 # ENTRY for parsing a delayed value
1901 rule delexpr: "{" expr "}" EOF {{ return expr }}
1903 rule wrstr<<ID>>: STR {{ setwrite(ID, dequote(STR)) }}
1905 rule defstmts<<ID>>: {{ d = 0 }}
1907 ( value {{ setdefault(ID, value, 1) }}
1908 | NONE {{ setnodefault(ID) }}
1910 | FORMAT STR {{ setformat(ID, dequote(STR)) }}
1912 ( ALWAYS {{ setexported(ID) }}
1913 | USED {{ setexportable(ID) }}
1914 | NEVER {{ setnoexport(ID) }}
1916 | COMMENT STR {{ setcomment(ID, dequote(STR)); d = d | 4 }}
1917 | WRITE (wrstr<<ID>>)+
1920 rule define: DEFINE ID {{ newoption(ID) }}
1921 defstmts<<ID>> END {{ validdef(ID, defstmts) }}
1923 # ENTRY for parsing Options.lb file
1924 rule options: (define)* EOF {{ return 1 }}
1927 #=============================================================================
1929 #=============================================================================
1930 def writemakefileheader(file, fname):
1931 file.write("# File: %s is autogenerated\n" % fname)
1933 def writemakefilefooter(file, fname):
1934 file.write("\n\n%s: %s %s\n"
1935 % (os.path.basename(fname), os.path.abspath(sys.argv[0]), top_config_file))
1936 file.write("\t(cd %s ; export PYTHONPATH=%s/util/newconfig ; python %s %s %s)\n\n"
1937 % (os.getcwd(), treetop, sys.argv[0], sys.argv[1], sys.argv[2]))
1939 def writemakefilesettings(path):
1940 """ Write Makefile.settings to seperate the settings
1941 from the actual makefile creation."""
1943 global treetop, target_dir
1945 filename = os.path.join(path, "Makefile.settings")
1946 print "Creating", filename
1947 file = safe_open(filename, 'w+')
1948 writemakefileheader(file, filename)
1949 file.write("TOP:=%s\n" % (treetop))
1950 file.write("TARGET_DIR:=%s\n" % target_dir)
1951 writemakefilefooter(file, filename)
1954 def writeimagesettings(image):
1955 """Write Makefile.settings to seperate the settings
1956 from the actual makefile creation."""
1959 global global_options_by_order
1961 filename = os.path.join(image.gettargetdir(), "Makefile.settings")
1962 print "Creating", filename
1963 file = safe_open(filename, 'w+')
1964 writemakefileheader(file, filename)
1965 file.write("TOP:=%s\n" % (treetop))
1966 file.write("TARGET_DIR:=%s\n" % (image.gettargetdir()))
1969 for o in global_exported_options:
1971 for o in image.exported_options:
1972 if (not o in exported):
1975 file.write("export %s:=" % o.name)
1976 if (hasvalue(o.name, image)):
1977 file.write("%s" % getformated(o.name, image))
1980 file.write("export VARIABLES :=\n")
1982 file.write("export VARIABLES += %s\n" % o.name)
1984 writemakefilefooter(file,filename)
1987 # write the romimage makefile
1988 # let's try the Makefile
1989 # first, dump all the -D stuff
1991 def writeimagemakefile(image):
1992 makefilepath = os.path.join(image.gettargetdir(), "Makefile")
1993 print "Creating", makefilepath
1994 file = safe_open(makefilepath, 'w+')
1995 writemakefileheader(file, makefilepath)
1998 file.write("\nall: linuxbios.rom\n\n")
1999 file.write(".PHONY: all\n\n")
2000 #file.write("include cpuflags\n")
2001 # Putting "include cpuflags" in the Makefile has the problem that the
2002 # cpuflags file would be generated _after_ we want to include it.
2003 # Instead, let make do the work of computing CPUFLAGS:
2004 file.write("# Get the value of TOP, VARIABLES, and several other variables.\n")
2005 file.write("include Makefile.settings\n\n")
2006 file.write("# Function to create an item like -Di586 or -DCONFIG_MAX_CPUS='1' or -Ui686\n")
2007 file.write("D_item = $(if $(subst undefined,,$(origin $1)),-D$1$(if $($1),='$($1)',),-U$1)\n\n")
2008 file.write("# Compute the value of CPUFLAGS here during make's first pass.\n")
2009 file.write("CPUFLAGS := $(foreach _var_,$(VARIABLES),$(call D_item,$(_var_)))\n\n")
2011 for i in image.getuserdefines():
2012 file.write("%s\n" %i)
2015 # print out all the object dependencies
2016 file.write("\n# object dependencies (objectrules:)\n")
2017 file.write("INIT-OBJECTS :=\n")
2018 file.write("OBJECTS :=\n")
2019 file.write("DRIVER :=\n")
2020 file.write("\nSOURCES :=\n")
2021 for irule, init in image.getinitobjectrules().items():
2024 file.write("INIT-OBJECTS += %s\n" % (i_name))
2025 file.write("SOURCES += %s\n" % (i_source))
2027 for objrule, obj in image.getobjectrules().items():
2030 file.write("OBJECTS += %s\n" % (obj_name))
2031 file.write("SOURCES += %s\n" % (obj_source))
2034 file.write("OBJECTS += static.o\n")
2035 file.write("SOURCES += static.c\n")
2037 for driverrule, driver in image.getdriverrules().items():
2038 obj_name = driver[0]
2039 obj_source = driver[1]
2040 file.write("DRIVER += %s\n" % (obj_name))
2041 file.write("SOURCES += %s\n" % (obj_source))
2043 # Print out all ldscript.ld dependencies.
2044 file.write("\n# ldscript.ld dependencies:\n")
2045 file.write("LDSUBSCRIPTS-1 := \n" )
2046 for script in image.getldscripts():
2047 file.write("LDSUBSCRIPTS-1 += %s\n" % topify(script))
2049 # Print out the dependencies for crt0_includes.h
2050 file.write("\n# Dependencies for crt0_includes.h\n")
2051 file.write("CRT0_INCLUDES:=\n")
2052 for inc in image.getinitincludes():
2053 if (local_path.match(inc)):
2054 file.write("CRT0_INCLUDES += %s\n" % inc)
2056 file.write("CRT0_INCLUDES += $(TOP)/src/%s\n" % inc)
2058 # Print out the user defines.
2059 file.write("\n# userdefines:\n")
2061 # Print out the base rules.
2062 # Need to have a rule that counts on 'all'.
2063 file.write("\n# mainrulelist:")
2065 # Print out any user rules.
2066 file.write("\n# From makerule or docipl commands:\n")
2068 file.write("\n# initobjectrules:\n")
2069 for irule, init in image.getinitobjectrules().items():
2070 source = topify(init[1])
2073 # for .S, .o depends on .s
2074 file.write("%s: %s.s\n" % (init[0], init[3]))
2075 file.write("\t@echo $(CC) ... -o $@ $<\n")
2076 file.write("\t$(CC) -c $(CPU_OPT) -o $@ $<\n")
2077 # and .s depends on .S
2078 file.write("%s.s: %s\n" % (init[3], source))
2079 file.write("\t@echo $(CPP) ... $< > $@\n")
2080 # Note: next 2 lines are ONE output line!
2081 file.write("\t$(CPP) $(CPPFLAGS) $< ")
2082 file.write(">$@.new && mv $@.new $@\n")
2084 file.write("%s: %s\n" % (init[0], source))
2085 file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
2087 file.write("\n# objectrules:\n")
2088 for objrule, obj in image.getobjectrules().items():
2089 source = topify(obj[1])
2092 # for .S, .o depends on .s
2093 file.write("%s: %s.s\n" % (obj[0], obj[3]))
2094 file.write("\t@echo $(CC) ... -o $@ $<\n")
2095 file.write("\t$(CC) -c $(CPU_OPT) -o $@ $<\n")
2096 # and .s depends on .S
2097 file.write("%s.s: %s\n" % (obj[3], source))
2098 file.write("\t@echo $(CPP) ... $< > $@\n")
2099 # Note: next 2 lines are ONE output line!
2100 file.write("\t$(CPP) $(CPPFLAGS) $< ")
2101 file.write(">$@.new && mv $@.new $@\n")
2103 file.write("%s: %s\n" % (obj[0], source))
2104 file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
2105 #file.write("%s\n" % objrule[2])
2107 for driverrule, driver in image.getdriverrules().items():
2108 source = topify(driver[1])
2109 file.write("%s: %s\n" % (driver[0], source))
2110 file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
2111 #file.write("%s\n" % objrule[2])
2113 # special rule for chip_target.c
2114 file.write("static.o: static.c\n")
2115 file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
2117 # Print out the rules that will make cause the files
2118 # generated by NLBConfig.py to be remade if any dependencies change.
2120 file.write("\n# Remember the automatically generated files\n")
2121 file.write("GENERATED:=\n")
2122 for genfile in ['Makefile',
2125 'LinuxBIOSDoc.config' ]:
2126 file.write("GENERATED += %s\n" % genfile)
2127 file.write("GENERATED += %s\n" % image.getincludefilename())
2129 keys = global_options_by_order
2131 file.write("\necho:\n")
2133 file.write("\t@echo %s='$(%s)'\n"% (key,key))
2135 for i, m in image.getmakerules().items():
2136 file.write("%s: " %i)
2137 for i in m.dependency:
2138 file.write("%s " % i)
2141 file.write("\t%s\n" % i)
2142 writemakefilefooter(file, makefilepath)
2146 def writemakefile(path):
2147 makefilepath = os.path.join(path, "Makefile")
2148 print "Creating", makefilepath
2149 file = safe_open(makefilepath, 'w+')
2150 writemakefileheader(file, makefilepath)
2153 file.write("\nall:")
2155 file.write(" %s" % i.name)
2157 file.write("include Makefile.settings\n\n")
2158 for i, o in romimages.items():
2159 file.write("%s/linuxbios.rom:\n" % o.getname())
2160 file.write("\tif (cd %s; \\\n" % o.getname())
2161 file.write("\t\tmake linuxbios.rom)\\\n")
2162 file.write("\tthen true; else exit 1; fi;\n\n")
2163 file.write("clean: ")
2164 for i in romimages.keys():
2165 file.write(" %s-clean" % i)
2167 for i, o in romimages.items():
2168 file.write("%s-clean:\n" % o.getname())
2169 file.write("\t(cd %s; make clean)\n\n" % o.getname())
2172 file.write("%s:" % i.name)
2174 file.write(" %s/linuxbios.rom " % j)
2176 file.write("\t cat ")
2178 file.write(" %s/linuxbios.rom " % j)
2179 file.write("> %s\n\n" %i.name)
2182 file.write(".PHONY: all clean")
2183 for i in romimages.keys():
2184 file.write(" %s-clean" % i)
2185 for i, o in romimages.items():
2186 file.write(" %s/linuxbios.rom" % o.getname())
2189 writemakefilefooter(file, makefilepath)
2192 def writeinitincludes(image):
2193 global include_pattern
2194 filepath = os.path.join(image.gettargetdir(), image.getincludefilename())
2195 print "Creating", filepath
2196 outfile = safe_open(filepath, 'w+')
2197 if (image.newformat()):
2198 infile = safe_open(image.getinitfile(), 'r')
2200 line = infile.readline()
2202 p = include_pattern.match(line)
2204 for i in image.getinitincludes():
2205 inc = image.getinitinclude(i)
2206 if (inc.getstring() == p.group(1)):
2207 outfile.write("#include \"%s\"\n" % inc.getpath())
2210 line = infile.readline()
2214 for i in image.getinitincludes():
2215 outfile.write("#include <%s>\n" % i)
2218 def writeldoptions(image):
2219 """Write ldoptions file."""
2220 filename = os.path.join(image.gettargetdir(), "ldoptions")
2221 print "Creating", filename
2222 file = safe_open(filename, 'w+')
2223 for o in global_exported_options:
2224 if (hasvalue(o.name, image) and IsInt(getoption(o.name, image))):
2225 file.write("%s = %s;\n" % (o.name, getformated(o.name, image)))
2226 for o in image.exported_options:
2227 if (not o in global_exported_options and hasvalue(o.name, image) and IsInt(getoption(o.name, image))):
2228 file.write("%s = %s;\n" % (o.name, getformated(o.name, image)))
2231 def dumptree(part, lvl):
2232 debug.info(debug.dumptree, "DUMPTREE ME is")
2234 # dump the siblings -- actually are there any? not sure
2236 debug.info(debug.dumptree, "DUMPTREE SIBLINGS are")
2237 kid = part.next_sibling
2240 kid = kid.next_sibling
2242 debug.info(debug.dumptree, "DUMPTREE KIDS are")
2243 #for kid in part.children:
2245 dumptree(part.children, lvl+1)
2246 kid = part.next_sibling
2249 dumptree(kid.children, lvl + 1)
2250 kid = kid.next_sibling
2251 debug.info(debug.dumptree, "DONE DUMPTREE")
2253 def writecode(image):
2254 filename = os.path.join(img_dir, "static.c")
2255 print "Creating", filename
2256 file = safe_open(filename, 'w+')
2257 file.write("#include <device/device.h>\n")
2258 file.write("#include <device/pci.h>\n")
2259 for path in image.getconfigincludes().values():
2260 file.write("#include \"%s\"\n" % path)
2261 gencode(image.getroot(), file, 0)
2262 gencode(image.getroot(), file, 1)
2265 def gencode(part, file, pass_num):
2266 debug.info(debug.gencode, "GENCODE ME is")
2267 part.gencode(file, pass_num)
2268 # dump the siblings -- actually are there any? not sure
2269 debug.info(debug.gencode, "GENCODE SIBLINGS are")
2270 kid = part.next_sibling
2272 kid.gencode(file, pass_num)
2273 kid = kid.next_sibling
2274 # now dump the children
2275 debug.info(debug.gencode, "GENCODE KIDS are")
2277 gencode(part.children, file, pass_num)
2278 kid = part.next_sibling
2281 gencode(kid.children, file, pass_num)
2282 kid = kid.next_sibling
2283 debug.info(debug.gencode, "DONE GENCODE")
2286 """Add any run-time checks to verify that parsing the configuration
2289 for image in romimages.values():
2290 print("Verifying ROMIMAGE %s" % image.name)
2291 if (image.newformat() and image.getinitfile() == ''):
2292 fatal("An init file must be specified")
2293 for op in image.exported_options:
2294 if (getoptionvalue(op.name, op, image) == 0 and getoptionvalue(op.name, op, 0) == 0):
2295 warning("Exported option %s has no value (check Options.lb)" % op.name);
2296 print("Verifing global options")
2297 for op in global_exported_options:
2298 if (getoptionvalue(op.name, op, 0) == 0):
2299 notice("Exported option %s has no value (check Options.lb)" % op.name);
2301 #=============================================================================
2303 #=============================================================================
2304 if __name__=='__main__':
2305 from sys import argv
2307 fatal("Args: <file> <path to linuxbios>")
2309 top_config_file = os.path.abspath(sys.argv[1])
2311 treetop = os.path.abspath(sys.argv[2])
2313 # Now read in the customizing script...
2315 fp = safe_open(argv[1], 'r')
2316 if (not parse('board', fp.read())):
2317 fatal("Could not parse file")
2322 # no longer need to check if an options has been used
2325 for image_name, image in romimages.items():
2326 if (debug.level(debug.dumptree)):
2327 debug.info(debug.dumptree, "DEVICE TREE:")
2328 dumptree(image.getroot(), 0)
2330 img_dir = image.gettargetdir()
2331 if not os.path.isdir(img_dir):
2332 print "Creating directory %s" % img_dir
2333 os.makedirs(img_dir)
2335 if (debug.level(debug.dump)):
2336 for i in image.getinitincludes():
2337 debug.info(debug.dump, "crt0include file %s" % i)
2338 for i in image.getdriverrules().keys():
2339 debug.info(debug.dump, "driver file %s" % i)
2340 for i in image.getldscripts():
2341 debug.info(debug.dump, "ldscript file %s" % i)
2342 for i, m in image.getmakerules().items():
2343 debug.info(debug.dump, " makerule %s dep %s act %s" % (i, m.dependency, m.actions))
2346 writeimagesettings(image)
2347 writeinitincludes(image)
2348 writeimagemakefile(image)
2349 writeldoptions(image)
2351 writemakefilesettings(target_dir)
2352 writemakefile(target_dir)