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)
1028 fatal("Option %s undefined (missing use command?)" % name)
1030 v = getdict(image.getvalues(), name)
1032 v = getdict(global_option_values, name)
1035 def getoption(name, image):
1036 """option must be declared before being used in a part
1037 if we're not processing a part, then we must
1038 be at the top level where all options are available"""
1040 global global_uses_options, alloptions, curimage
1042 #print "getoption: name %s image %s alloptions %s curimage %s\n\n" % (name, image, alloptions, curimage)
1043 curpart = partstack.tos()
1045 o = getdict(global_options, name)
1047 o = getdict(curpart.uses_options, name)
1049 print "curpart.uses_options is %s\n" % curpart.uses_options
1051 o = getdict(global_uses_options, name)
1052 v = getoptionvalue(name, o, image)
1054 v = getoptionvalue(name, o, 0)
1056 fatal("No value for option %s" % name)
1058 if (not (type(val) is types.StringType)):
1060 if (val == '' or val[0] != '{'):
1064 val = parse('delexpr', val)
1069 def setoption(name, value, imp):
1070 """Set an option from within a configuration file. Normally this
1071 is only permitted in the target (top level) configuration file.
1072 If 'imp' is true, then set an option implicitly (e.g. 'arch'
1073 and 'mainboard' statements). Implicit options can be set anywhere
1074 the statements are legal, but also performs an implicit 'uses'
1077 global loc, global_options, global_option_values, curimage
1079 curpart = partstack.tos()
1080 if (not imp and curpart):
1081 fatal("Options may only be set in target configuration file")
1085 o = getdict(curpart.uses_options, name)
1087 o = getdict(global_uses_options, name)
1089 fatal("Attempt to set nonexistent option %s (missing USES?)" % name)
1090 v = getoptionvalue(name, o, curimage)
1092 v = newoptionvalue(name, curimage)
1095 def exportoption(op, exported_options):
1096 if (not op.isexportable()):
1098 if (not op in exported_options):
1099 exported_options.append(op)
1101 def setdefault(name, value, isdef):
1102 """Set the default value of an option from within a configuration
1103 file. This is permitted from any configuration file, but will
1104 result in a warning if the default is set more than once.
1105 If 'isdef' is set, we're defining the option in Options.lb so
1106 there is no need for 'uses'."""
1108 global loc, global_options, curimage
1111 o = getdict(global_options, name)
1116 curpart = partstack.tos()
1118 o = getdict(curpart.uses_options, name)
1120 o = getdict(global_uses_options, name)
1122 fatal("Attempt to set default for nonexistent option %s (missing USES?)" % name)
1125 v = getoptionvalue(name, o, image)
1127 v = newoptionvalue(name, image)
1130 def setnodefault(name):
1131 global loc, global_options
1132 o = getdict(global_options, name)
1135 v = getdict(global_option_values, name)
1137 warning("removing default for %s" % name)
1138 del global_option_values[name]
1140 def setcomment(name, value):
1141 global loc, global_options
1142 o = getdict(global_options, name)
1144 fatal("setcomment: %s not here" % name)
1145 o.setcomment(value, loc)
1147 def setexported(name):
1148 global global_options
1149 o = getdict(global_options, name)
1151 fatal("setexported: %s not here" % name)
1153 global_exported_options.append(o)
1155 def setnoexport(name):
1156 global global_options
1157 o = getdict(global_options, name)
1159 fatal("setnoexport: %s not here" % name)
1161 if (o in global_exported_options):
1162 global_exported_options.remove(o)
1164 def setexportable(name):
1165 global global_options
1166 o = getdict(global_options, name)
1168 fatal("setexportable: %s not here" % name)
1171 def setformat(name, fmt):
1172 global global_options
1173 o = getdict(global_options, name)
1175 fatal("setformat: %s not here" % name)
1178 def getformated(name, image):
1179 global global_options, global_option_values
1180 o = getdict(global_options, name)
1181 v = getoption(name, image)
1185 def setwrite(name, part):
1186 global global_options
1187 o = getdict(global_options, name)
1189 fatal("setwrite: %s not here" % name)
1192 def hasvalue(name, image):
1193 global global_options
1194 o = getdict(global_options, name)
1199 v = getdict(image.getvalues(), name)
1201 v = getdict(global_option_values, name)
1204 def isset(name, part):
1205 global global_uses_options, global_option_values, curimage
1207 o = getdict(part.uses_options, name)
1209 o = getdict(global_uses_options, name)
1214 v = getdict(curimage.getvalues(), name)
1216 v = getdict(global_option_values, name)
1217 return (v != 0 and v.isset())
1219 def usesoption(name):
1220 global global_options, global_uses_options
1221 curpart = partstack.tos()
1223 curpart.usesoption(name)
1225 o = getdict(global_options, name)
1227 fatal("Can't use undefined option %s" % name)
1228 o1 = getdict(global_uses_options, name)
1231 setdict(global_uses_options, name, o)
1232 exportoption(o, global_exported_options)
1234 def validdef(name, defval):
1235 global global_options
1236 o = getdict(global_options, name)
1238 fatal("validdef: %s not here" % name)
1239 if ((defval & 1) != 1):
1240 fatal("Must specify default value for option %s" % name)
1241 if ((defval & 2) != 2):
1242 fatal("Must specify export for option %s" % name)
1243 if ((defval & 4) != 4):
1244 fatal("Must specify comment for option %s" % name)
1246 def loadoptions(path, file, rule):
1247 file = os.path.join('src', path, file)
1248 optionsfile = os.path.join(treetop, file)
1249 fp = safe_open(optionsfile, 'r')
1251 if (not parse(rule, fp.read())):
1252 fatal("Could not parse file")
1256 global curimage, dirstack
1257 if (path[0] == '/'):
1258 curimage.setinitfile(treetop + '/src/' + path)
1260 curimage.setinitfile(dirstack.tos() + '/' + path)
1261 print "Adding init file: %s" % path
1263 def addconfig(path):
1265 curpart = partstack.tos()
1266 curpart.addconfig(path)
1268 def addregister(field, value):
1270 curpart = partstack.tos()
1271 curpart.addregister(field, value)
1273 def addcrt0include(path):
1274 """we do the crt0include as a dictionary, so that if needed we
1275 can trace who added what when. Also it makes the keys
1278 curimage.addinitinclude(0, path)
1280 def addinitinclude(str, path):
1282 curimage.addinitinclude(dequote(str), path)
1284 def addldscript(path):
1285 global curimage, dirstack
1286 curdir = dirstack.tos()
1287 if (path[0] == '/'):
1288 fullpath = treetop + '/src/' + path
1290 fullpath = curdir + '/' + path
1291 debug.info(debug.statement, "fullpath :%s: curdir :%s: path :%s:" % (fullpath, curdir, path))
1292 curimage.addldscript(fullpath)
1296 curimage.setpayload(path)
1297 adduserdefine("PAYLOAD:=%s"%path)
1299 def startromimage(name):
1300 global romimages, curimage, target_dir, target_name
1301 curpart = partstack.tos()
1302 print "Configuring ROMIMAGE %s Curimage %s" % (name, curimage)
1303 print "Curpart is %s\n" % curpart
1304 o = getdict(romimages, name)
1306 fatal("romimage %s previously defined" % name)
1307 curimage = romimage(name)
1308 curimage.settargetdir(os.path.join(target_dir, name))
1309 #o = partobj(curimage, target_dir, 0, 'board', target_name)
1310 #curimage.setroot(o)
1311 setdict(romimages, name, curimage)
1312 dodir('/config', 'Config.lb')
1317 print "End ROMIMAGE"
1321 def mainboardsetup(path):
1322 global full_mainboard_path, mainboard_path
1323 mainboard_path = os.path.join('mainboard', path)
1324 loadoptions(mainboard_path, 'Options.lb', 'mainboardvariables')
1325 full_mainboard_path = os.path.join(treetop, 'src', 'mainboard', path)
1326 vendor = re.sub("/.*", "", path)
1327 part_number = re.sub("[^/]*/", "", path)
1328 setdefault('MAINBOARD', full_mainboard_path, 0)
1329 setdefault('MAINBOARD_VENDOR', vendor, 0)
1330 setdefault('MAINBOARD_PART_NUMBER', part_number, 0)
1333 global curimage, dirstack, partstack
1335 partdir = mainboard_path
1336 srcdir = os.path.join(treetop, 'src')
1337 fulldir = os.path.join(srcdir, partdir)
1338 type_name = flatten_name(partdir)
1339 newpart = partobj(curimage, fulldir, partstack.tos(), 'mainboard', \
1340 type_name, 0, 'chip')
1341 #print "Configuring PART %s" % (type)
1342 partstack.push(newpart)
1343 #print " new PART tos is now %s\n" %partstack.tos().info()
1344 dirstack.push(fulldir)
1345 loadoptions(mainboard_path, 'Options.lb', 'mainboardvariables')
1346 # special case for 'cpu' parts.
1347 # we could add a new function too, but this is rather trivial.
1348 # if the part is a cpu, and we haven't seen it before,
1349 # arrange to source the directory /cpu/'type'
1350 doconfigfile(srcdir, partdir, file, 'cfgfile')
1351 curimage.setroot(partstack.tos())
1354 def addbuildrom(filename, size, roms):
1356 print "Build ROM size %d" % size
1357 b = buildrom(filename, size, roms)
1360 def addinitobject(object_name):
1362 curimage.addinitobjectrule(object_name)
1364 def addobject(object_name):
1366 curimage.addobjectrule(object_name)
1368 def adddriver(driver_name):
1370 curimage.adddriverrule(driver_name)
1373 global target_dir, target_name
1374 print "Configuring TARGET %s" % name
1376 target_dir = os.path.join(os.path.dirname(loc.file()), name)
1377 if not os.path.isdir(target_dir):
1378 print "Creating directory %s" % target_dir
1379 os.makedirs(target_dir)
1380 print "Will place Makefile, crt0.S, etc. in %s" % target_dir
1385 if (cpu_type and (cpu_type != path)):
1386 fatal("Two different CPU types: %s and %s" % (cpu_type, path))
1387 srcdir = "/cpu/%s" % path
1388 dodir(srcdir, "Config.lb")
1391 def devicepart(type):
1392 global curimage, dirstack, partstack
1393 newpart = partobj(curimage, 0, partstack.tos(), type, \
1395 #print "Configuring PART %s" % (type)
1396 partstack.push(newpart)
1397 #print " new PART tos is now %s\n" %partstack.tos().info()
1398 # just push TOS, so that we can pop later.
1399 dirstack.push(dirstack.tos())
1401 def part(type, path, file, name):
1402 global curimage, dirstack, partstack
1403 partdir = os.path.join(type, path)
1404 srcdir = os.path.join(treetop, 'src')
1405 fulldir = os.path.join(srcdir, partdir)
1406 type_name = flatten_name(partdir)
1407 newpart = partobj(curimage, fulldir, partstack.tos(), type, \
1408 type_name, name, 'chip')
1409 #print "Configuring PART %s, path %s" % (type, path)
1410 partstack.push(newpart)
1411 #print " new PART tos is now %s\n" %partstack.tos().info()
1412 dirstack.push(fulldir)
1413 # special case for 'cpu' parts.
1414 # we could add a new function too, but this is rather trivial.
1415 # if the part is a cpu, and we haven't seen it before,
1416 # arrange to source the directory /cpu/'type'
1420 doconfigfile(srcdir, partdir, file, 'cfgfile')
1423 global dirstack, partstack
1424 curpart = partstack.tos()
1426 fatal("Trying to pop non-existent part")
1427 #print "End PART %s" % curpart.part
1428 # Warn if options are used without being set in this part
1429 for op in curpart.uses_options.keys():
1430 if (not isset(op, curpart)):
1431 notice("Option %s using default value %s" % (op, getformated(op, curpart.image)))
1432 oldpart = partstack.pop()
1434 #print "partstack.pop, TOS is now %s\n" % oldpart.info()
1436 def dodir(path, file):
1437 """dodir is like part but there is no new part"""
1439 # if the first char is '/', it is relative to treetop,
1440 # else relative to curdir
1441 # os.path.join screws up if the name starts with '/', sigh.
1442 print "Configuring DIR %s" % os.path.join(path, file)
1443 if (path[0] == '/'):
1444 fullpath = os.path.join(treetop, 'src')
1445 path = re.sub('^/*', '', path)
1447 fullpath = dirstack.tos()
1448 debug.info(debug.statement, "DODIR: path %s, fullpath %s" % (path, fullpath))
1449 dirstack.push(os.path.join(fullpath, path))
1450 doconfigfile(fullpath, path, file, 'cfgfile')
1455 return getoption(name, curimage)
1459 curimage.addmakerule(id)
1461 def adduserdefine(str):
1463 curimage.adduserdefine(str)
1465 def addaction(id, str):
1467 curimage.addmakeaction(id, str)
1469 def adddep(id, str):
1471 curimage.addmakedepend(id, str)
1473 def setarch(my_arch):
1474 """arch is 'different' ... darn it."""
1476 print "SETTING ARCH %s\n" % my_arch
1477 curimage.setarch(my_arch)
1478 setdefault('ARCH', my_arch, 1)
1479 part('arch', my_arch, 'Config.lb', 0)
1481 def doconfigfile(path, confdir, file, rule):
1482 rname = os.path.join(confdir, file)
1484 fullpath = os.path.join(path, rname)
1485 fp = safe_open(fullpath, 'r')
1486 if (not parse(rule, fp.read())):
1487 fatal("Could not parse file")
1491 #=============================================================================
1493 #=============================================================================
1494 def ternary(val, yes, no):
1495 debug.info(debug.statement, "ternary %s" % expr)
1496 debug.info(debug.statement, "expr %s a %d yes %d no %d"% (expr, a, yes, no))
1498 debug.info(debug.statement, "Ternary returns %d" % yes)
1501 debug.info(debug.statement, "Ternary returns %d" % no)
1505 """atoi is in the python library, but not strtol? Weird!"""
1506 return eval('int(%s)' % name)
1509 """ Is the given string an integer?"""
1517 a = re.sub("^\"", "", str)
1518 a = re.sub("\"$", "", a)
1519 # highly un-intuitive, need four \!
1520 a = re.sub("\\\\\"", "\"", a)
1523 def flatten_name(str):
1524 a = re.sub("[/-]", "_", str)
1528 """If the first part of <path> matches treetop, replace
1529 that part with $(TOP)"""
1530 if path[0:len(treetop)] == treetop:
1531 path = path[len(treetop):len(path)]
1532 if (path[0:1] == "/"):
1533 path = path[1:len(path)]
1534 path = "$(TOP)/" + path
1538 # to make if work without 2 passses, we use an old hack from SIMD, the
1539 # context bit. If the bit is 1, then ops get done, otherwise
1540 # ops don't get done. From the top level, context is always
1541 # 1. In an if, context depends on eval of the if condition
1547 # less general tokens should come first, otherwise they get matched
1549 token ACTION: 'action'
1550 token ADDACTION: 'addaction'
1551 token ALWAYS: 'always'
1553 token BUILDROM: 'buildrom'
1554 token COMMENT: 'comment'
1555 token CONFIG: 'config'
1557 token CPU_BUS: 'cpu_bus'
1559 token DEFAULT: 'default'
1560 token DEFINE: 'define'
1561 token DEPENDS: 'depends'
1562 token DEVICE: 'device'
1564 token DRIVER: 'driver'
1570 token EXPORT: 'export'
1571 token FORMAT: 'format'
1574 token INITOBJECT: 'initobject'
1575 token INITINCLUDE: 'initinclude'
1578 token LDSCRIPT: 'ldscript'
1579 token LOADOPTIONS: 'loadoptions'
1580 token MAINBOARD: 'mainboard'
1581 token MAINBOARDINIT: 'mainboardinit'
1582 token MAKEDEFINE: 'makedefine'
1583 token MAKERULE: 'makerule'
1585 token NEVER: 'never'
1587 token NORTHBRIDGE: 'northbridge'
1588 token OBJECT: 'object'
1589 token OPTION: 'option'
1590 token PAYLOAD: 'payload'
1592 token PRINT: 'print'
1593 token REGISTER: 'register'
1594 token ROMIMAGE: 'romimage'
1595 token SOUTHBRIDGE: 'southbridge'
1596 token SUPERIO: 'superio'
1597 token TARGET: 'target'
1600 token WRITE: 'write'
1602 token HEX_NUM: '[0-9a-fA-F]+'
1603 token HEX_PREFIX: '0x'
1604 # Why is path separate? Because paths to resources have to at least
1605 # have a slash, we thinks
1606 token PATH: r'[-a-zA-Z0-9_.][-a-zA-Z0-9/_.]+[-a-zA-Z0-9_.]+'
1607 # Dir's on the other hand are abitrary
1608 # this may all be stupid.
1609 token DIRPATH: r'[-a-zA-Z0-9_$()./]+'
1610 token ID: r'[a-zA-Z_.]+[a-zA-Z0-9_.]*'
1611 token DELEXPR: r'{([^}]+|\\.)*}'
1612 token STR: r'"([^\\"]+|\\.)*"'
1613 token RAWTEXT: r'.*'
1620 token APIC_CLUSTER: 'apic_cluster'
1622 token CPU_BUS: 'cpu_bus'
1623 token PCI_DOMAIN: 'pci_domain'
1626 rule expr: logical {{ l = logical }}
1627 ( "&&" logical {{ l = l and logical }}
1628 | "||" logical {{ l = l or logical }}
1631 rule logical: factor {{ n = factor }}
1632 ( "[+]" factor {{ n = n+factor }}
1633 | "-" factor {{ n = n-factor }}
1636 rule factor: term {{ v = term }}
1637 ( "[*]" term {{ v = v*term }}
1638 | "/" term {{ v = v/term }}
1639 | "<<" term {{ v = v << term }}
1640 | ">=" term {{ v = (v < term)}}
1643 # A term is a number, variable, or an expression surrounded by parentheses
1644 rule term: NUM {{ return long(NUM, 10) }}
1645 | HEX_PREFIX HEX_NUM {{ return long(HEX_NUM, 16) }}
1646 | ID {{ return lookup(ID) }}
1647 | unop {{ return unop }}
1648 | "\\(" expr "\\)" {{ return expr }}
1650 rule unop: "!" expr {{ return not(expr) }}
1652 rule partend<<C>>: (stmt<<C>>)* END {{ if (C): partpop()}}
1654 # This is needed because the legacy cpu command could not distinguish
1655 # between cpu vendors. It should just be PATH, but getting this change
1656 # into the source tree will be tricky...
1657 # DO NOT USE ID AS IT MAY GO AWAY IN THE FUTURE
1658 rule partid: ID {{ return ID }}
1659 | PATH {{ return PATH }}
1661 # rule parttype: NORTHBRIDGE {{ return 'northbridge' }}
1662 # | SUPERIO {{ return 'superio' }}
1663 # | PMC {{ return 'pmc' }}
1664 # | SOUTHBRIDGE {{ return 'southbridge' }}
1665 # | CPU {{ return 'cpu' }}
1666 # | CHIP {{ return '' }}
1668 rule parttype: CHIP {{ return '' }}
1670 rule partdef<<C>>: {{ name = 0 }}
1672 [ STR {{ name = dequote(STR) }}
1673 ] {{ if (C): part(parttype, partid, 'Config.lb', name) }}
1676 rule arch<<C>>: ARCH ID {{ if (C): setarch(ID) }}
1679 rule mainboardinit<<C>>:
1680 MAINBOARDINIT DIRPATH {{ if (C): addcrt0include(DIRPATH)}}
1682 rule initinclude<<C>>:
1685 DIRPATH {{ if (C): addinitinclude(STR, DIRPATH)}}
1687 rule initobject<<C>>:
1688 INITOBJECT DIRPATH {{ if (C): addinitobject(DIRPATH)}}
1690 rule object<<C>>: OBJECT DIRPATH {{ if (C): addobject(DIRPATH)}}
1692 rule driver<<C>>: DRIVER DIRPATH {{ if (C): adddriver(DIRPATH)}}
1694 rule dir<<C>>: DIR DIRPATH {{ if (C): dodir(DIRPATH, 'Config.lb') }}
1696 rule default<<C>>: DEFAULT ID EQ value {{ if (C): setdefault(ID, value, 0) }}
1698 rule ldscript<<C>>: LDSCRIPT DIRPATH {{ if (C): addldscript(DIRPATH) }}
1700 rule iif<<C>>: IF ID {{ c = lookup(ID) }}
1702 [ ELSE (stmt<<C and not c>>)* ]
1705 rule depsacts<<ID, C>>:
1706 ( DEPENDS STR {{ if (C): adddep(ID, STR) }}
1707 | ACTION STR {{ if (C): addaction(ID, STR) }}
1710 rule makerule<<C>>: MAKERULE DIRPATH {{ if (C): addrule(DIRPATH) }}
1711 depsacts<<DIRPATH, C>>
1714 rule makedefine<<C>>:
1715 MAKEDEFINE RAWTEXT {{ if (C): adduserdefine(RAWTEXT) }}
1717 rule addaction<<C>>:
1718 ADDACTION ID STR {{ if (C): addaction(ID, STR) }}
1720 rule init<<C>>: INIT DIRPATH {{ if (C): addinit(DIRPATH) }}
1722 rule field: STR {{ return STR }}
1724 rule register<<C>>: REGISTER field '=' STR {{ if (C): addregister(field, STR) }}
1726 rule enable<<C>>: {{ val = 1 }}
1729 ) {{ if(C): partstack.tos().set_enabled(val) }}
1731 rule resource<<C>>: {{ type = "" }}
1732 ( IO {{ type = "IORESOURCE_FIXED | IORESOURCE_ASSIGNED | IORESOURCE_IO" }}
1733 | MEM {{ type = "IORESOURCE_FIXED | IORESOURCE_ASSIGNED | IORESOURCE_MEM" }}
1734 | IRQ {{ type = "IORESOURCE_FIXED | IORESOURCE_ASSIGNED | IORESOURCE_IRQ" }}
1735 | DRQ {{ type = "IORESOURCE_FIXED | IORESOURCE_ASSIGNED | IORESOURCE_DRQ" }}
1737 term '=' {{ index = term }}
1738 term {{ value = term }}
1739 {{ if (C): partstack.tos().add_resource(type, index, value) }}
1742 rule resources<<C>>: {{ if (C): partstack.tos().start_resources() }}
1744 {{ if (C): partstack.tos().end_resources() }}
1747 rule pci<<C>>: PCI {{ if (C): devicepart('pci') }}
1749 HEX_NUM {{ slot = int(HEX_NUM,16) }}
1750 '.' HEX_NUM {{ function = int(HEX_NUM, 16) }}
1751 {{ if (C): partstack.tos().addpcipath(slot, function) }}
1752 rule pci_domain<<C>>:
1753 PCI_DOMAIN {{ if (C): devicepart('pci_domain') }}
1754 HEX_NUM {{ pci_domain = int(HEX_NUM, 16) }}
1755 {{ if (C): partstack.tos().addpci_domainpath(pci_domain) }}
1757 rule pnp<<C>>: PNP {{ if (C): devicepart('pnp') }}
1758 HEX_NUM {{ port = int(HEX_NUM,16) }}
1759 '.' HEX_NUM {{ device = int(HEX_NUM, 16) }}
1760 {{ if (C): partstack.tos().addpnppath(port, device) }}
1762 rule i2c<<C>>: I2C {{ if (C): devicepart('i2c') }}
1763 HEX_NUM {{ device = int(HEX_NUM, 16) }}
1764 {{ if (C): partstack.tos().addi2cpath(device) }}
1766 rule apic<<C>>: APIC {{ if (C): devicepart('apic') }}
1767 HEX_NUM {{ apic_id = int(HEX_NUM, 16) }}
1768 {{ if (C): partstack.tos().addapicpath(apic_id) }}
1770 rule apic_cluster<<C>>: APIC_CLUSTER {{ if (C): devicepart('apic_cluster') }}
1771 HEX_NUM {{ cluster = int(HEX_NUM, 16) }}
1772 {{ if (C): partstack.tos().addapic_clusterpath(cluster) }}
1774 rule cpu<<C>>: CPU {{ if (C): devicepart('cpu') }}
1775 HEX_NUM {{ id = int(HEX_NUM, 16) }}
1776 {{ if (C): partstack.tos().addcpupath(id) }}
1778 rule cpu_bus<<C>>: CPU_BUS {{ if (C): devicepart('cpu_bus') }}
1779 HEX_NUM {{ id = int(HEX_NUM, 16) }}
1780 {{ if (C): partstack.tos().addcpu_buspath(id) }}
1783 pci<<C>> {{ return pci }}
1784 | pci_domain<<C>> {{ return pci_domain }}
1785 | pnp<<C>> {{ return pnp }}
1786 | i2c<<C>> {{ return i2c }}
1787 | apic<<C>> {{ return apic }}
1788 | apic_cluster<<C>> {{ return apic_cluster }}
1789 | cpu<<C>> {{ return cpu }}
1790 | cpu_bus<<C>> {{ return cpu_bus }}
1792 rule prtval: expr {{ return str(expr) }}
1793 | STR {{ return STR }}
1795 rule prtlist: prtval {{ el = "%(" + prtval }}
1796 ( "," prtval {{ el = el + "," + prtval }}
1797 )* {{ return el + ")" }}
1799 rule prtstmt<<C>>: PRINT STR {{ val = STR }}
1800 [ "," prtlist {{ val = val + prtlist }}
1801 ] {{ if (C): print eval(val) }}
1803 rule config<<C>>: CONFIG PATH {{ if (C): addconfig(PATH) }}
1805 rule device<<C>>: DEVICE dev_path<<C>>
1810 rule stmt<<C>>: arch<<C>> {{ return arch}}
1811 | addaction<<C>> {{ return addaction }}
1812 | config<<C>> {{ return config}}
1813 | default<<C>> {{ return default}}
1814 | dir<<C>> {{ return dir}}
1815 | driver<<C>> {{ return driver }}
1816 | iif<<C>> {{ return iif }}
1817 | init<<C>> {{ return init }}
1818 | initinclude<<C>> {{ return initinclude }}
1819 | initobject<<C>> {{ return initobject }}
1820 | ldscript<<C>> {{ return ldscript}}
1821 | mainboardinit<<C>> {{ return mainboardinit }}
1822 | makedefine<<C>> {{ return makedefine }}
1823 | makerule<<C>> {{ return makerule }}
1824 | object<<C>> {{ return object }}
1825 | option<<C>> {{ return option }}
1826 | partdef<<C>> {{ return partdef }}
1827 | prtstmt<<C>> {{ return prtstmt }}
1828 | register<<C>> {{ return register }}
1829 | device<<C>> {{ return device }}
1831 # ENTRY for parsing Config.lb file
1832 rule cfgfile: (uses<<1>>)*
1836 rule cfgfile: (uses<<1>>)*
1840 rule usesid<<C>>: ID {{ if (C): usesoption(ID) }}
1842 rule uses<<C>>: USES (usesid<<C>>)+
1844 rule mainboardvariables: (uses<<1>>)*
1849 rule value: STR {{ return dequote(STR) }}
1850 | expr {{ return expr }}
1851 | DELEXPR {{ return DELEXPR }}
1853 rule option<<C>>: OPTION ID EQ value {{ if (C): setoption(ID, value, 0) }}
1855 rule opif<<C>>: IF ID {{ c = lookup(ID) }}
1856 (opstmt<<C and c>>)*
1857 [ ELSE (opstmt<<C and not c>>)* ]
1860 rule opstmt<<C>>: option<<C>>
1864 rule payload<<C>>: PAYLOAD DIRPATH {{ if (C): payload(DIRPATH) }}
1867 MAINBOARD PATH {{ mainboardsetup(PATH) }}
1869 rule romif<<C>>: IF ID {{ c = lookup(ID) }}
1870 (romstmt<<C and c>>)*
1871 [ ELSE (romstmt<<C and not c>>)* ]
1874 rule romstmt<<C>>: romif<<C>>
1878 rule romimage: ROMIMAGE STR {{ startromimage(dequote(STR)) }}
1880 END {{ endromimage() }}
1882 rule roms: STR {{ s = '[' + STR }}
1883 ( STR {{ s = s + "," + STR }}
1884 )* {{ return eval(s + ']') }}
1886 rule buildrom: BUILDROM DIRPATH expr roms {{ addbuildrom(DIRPATH, expr, roms) }}
1888 rule romstmts: romimage
1892 # ENTRY for parsing root part
1893 rule board: {{ loadoptions("config", "Options.lb", "options") }}
1894 TARGET DIRPATH {{ target(DIRPATH) }}
1899 # ENTRY for parsing a delayed value
1900 rule delexpr: "{" expr "}" EOF {{ return expr }}
1902 rule wrstr<<ID>>: STR {{ setwrite(ID, dequote(STR)) }}
1904 rule defstmts<<ID>>: {{ d = 0 }}
1906 ( value {{ setdefault(ID, value, 1) }}
1907 | NONE {{ setnodefault(ID) }}
1909 | FORMAT STR {{ setformat(ID, dequote(STR)) }}
1911 ( ALWAYS {{ setexported(ID) }}
1912 | USED {{ setexportable(ID) }}
1913 | NEVER {{ setnoexport(ID) }}
1915 | COMMENT STR {{ setcomment(ID, dequote(STR)); d = d | 4 }}
1916 | WRITE (wrstr<<ID>>)+
1919 rule define: DEFINE ID {{ newoption(ID) }}
1920 defstmts<<ID>> END {{ validdef(ID, defstmts) }}
1922 # ENTRY for parsing Options.lb file
1923 rule options: (define)* EOF {{ return 1 }}
1926 #=============================================================================
1928 #=============================================================================
1929 def writemakefileheader(file, fname):
1930 file.write("# File: %s is autogenerated\n" % fname)
1932 def writemakefilefooter(file, fname):
1933 file.write("\n\n%s: %s %s\n"
1934 % (os.path.basename(fname), os.path.abspath(sys.argv[0]), top_config_file))
1935 file.write("\t(cd %s ; %s %s %s)\n\n"
1936 % (os.getcwd(), sys.argv[0], sys.argv[1], sys.argv[2]))
1938 def writemakefilesettings(path):
1939 """ Write Makefile.settings to seperate the settings
1940 from the actual makefile creation."""
1942 global treetop, target_dir
1944 filename = os.path.join(path, "Makefile.settings")
1945 print "Creating", filename
1946 file = safe_open(filename, 'w+')
1947 writemakefileheader(file, filename)
1948 file.write("TOP:=%s\n" % (treetop))
1949 file.write("TARGET_DIR:=%s\n" % target_dir)
1950 writemakefilefooter(file, filename)
1953 def writeimagesettings(image):
1954 """Write Makefile.settings to seperate the settings
1955 from the actual makefile creation."""
1958 global global_options_by_order
1960 filename = os.path.join(image.gettargetdir(), "Makefile.settings")
1961 print "Creating", filename
1962 file = safe_open(filename, 'w+')
1963 writemakefileheader(file, filename)
1964 file.write("TOP:=%s\n" % (treetop))
1965 file.write("TARGET_DIR:=%s\n" % (image.gettargetdir()))
1968 for o in global_exported_options:
1970 for o in image.exported_options:
1971 if (not o in exported):
1974 file.write("export %s:=" % o.name)
1975 if (hasvalue(o.name, image)):
1976 file.write("%s" % getformated(o.name, image))
1979 file.write("export VARIABLES :=\n")
1981 file.write("export VARIABLES += %s\n" % o.name)
1983 writemakefilefooter(file,filename)
1986 # write the romimage makefile
1987 # let's try the Makefile
1988 # first, dump all the -D stuff
1990 def writeimagemakefile(image):
1991 makefilepath = os.path.join(image.gettargetdir(), "Makefile")
1992 print "Creating", makefilepath
1993 file = safe_open(makefilepath, 'w+')
1994 writemakefileheader(file, makefilepath)
1997 file.write("\nall: linuxbios.rom\n\n")
1998 file.write(".PHONY: all\n\n")
1999 #file.write("include cpuflags\n")
2000 # Putting "include cpuflags" in the Makefile has the problem that the
2001 # cpuflags file would be generated _after_ we want to include it.
2002 # Instead, let make do the work of computing CPUFLAGS:
2003 file.write("# Get the value of TOP, VARIABLES, and several other variables.\n")
2004 file.write("include Makefile.settings\n\n")
2005 file.write("# Function to create an item like -Di586 or -DCONFIG_MAX_CPUS='1' or -Ui686\n")
2006 file.write("D_item = $(if $(subst undefined,,$(origin $1)),-D$1$(if $($1),='$($1)',),-U$1)\n\n")
2007 file.write("# Compute the value of CPUFLAGS here during make's first pass.\n")
2008 file.write("CPUFLAGS := $(foreach _var_,$(VARIABLES),$(call D_item,$(_var_)))\n\n")
2010 for i in image.getuserdefines():
2011 file.write("%s\n" %i)
2014 # print out all the object dependencies
2015 file.write("\n# object dependencies (objectrules:)\n")
2016 file.write("INIT-OBJECTS :=\n")
2017 file.write("OBJECTS :=\n")
2018 file.write("DRIVER :=\n")
2019 file.write("\nSOURCES :=\n")
2020 for irule, init in image.getinitobjectrules().items():
2023 file.write("INIT-OBJECTS += %s\n" % (i_name))
2024 file.write("SOURCES += %s\n" % (i_source))
2026 for objrule, obj in image.getobjectrules().items():
2029 file.write("OBJECTS += %s\n" % (obj_name))
2030 file.write("SOURCES += %s\n" % (obj_source))
2033 file.write("OBJECTS += static.o\n")
2034 file.write("SOURCES += static.c\n")
2036 for driverrule, driver in image.getdriverrules().items():
2037 obj_name = driver[0]
2038 obj_source = driver[1]
2039 file.write("DRIVER += %s\n" % (obj_name))
2040 file.write("SOURCES += %s\n" % (obj_source))
2042 # Print out all ldscript.ld dependencies.
2043 file.write("\n# ldscript.ld dependencies:\n")
2044 file.write("LDSUBSCRIPTS-1 := \n" )
2045 for script in image.getldscripts():
2046 file.write("LDSUBSCRIPTS-1 += %s\n" % topify(script))
2048 # Print out the dependencies for crt0_includes.h
2049 file.write("\n# Dependencies for crt0_includes.h\n")
2050 file.write("CRT0_INCLUDES:=\n")
2051 for inc in image.getinitincludes():
2052 if (local_path.match(inc)):
2053 file.write("CRT0_INCLUDES += %s\n" % inc)
2055 file.write("CRT0_INCLUDES += $(TOP)/src/%s\n" % inc)
2057 # Print out the user defines.
2058 file.write("\n# userdefines:\n")
2060 # Print out the base rules.
2061 # Need to have a rule that counts on 'all'.
2062 file.write("\n# mainrulelist:")
2064 # Print out any user rules.
2065 file.write("\n# From makerule or docipl commands:\n")
2067 file.write("\n# initobjectrules:\n")
2068 for irule, init in image.getinitobjectrules().items():
2069 source = topify(init[1])
2072 # for .S, .o depends on .s
2073 file.write("%s: %s.s\n" % (init[0], init[3]))
2074 file.write("\t@echo $(CC) ... -o $@ $<\n")
2075 file.write("\t$(CC) -c $(CPU_OPT) -o $@ $<\n")
2076 # and .s depends on .S
2077 file.write("%s.s: %s\n" % (init[3], source))
2078 file.write("\t@echo $(CPP) ... $< > $@\n")
2079 # Note: next 2 lines are ONE output line!
2080 file.write("\t$(CPP) $(CPPFLAGS) $< ")
2081 file.write(">$@.new && mv $@.new $@\n")
2083 file.write("%s: %s\n" % (init[0], source))
2084 file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
2086 file.write("\n# objectrules:\n")
2087 for objrule, obj in image.getobjectrules().items():
2088 source = topify(obj[1])
2091 # for .S, .o depends on .s
2092 file.write("%s: %s.s\n" % (obj[0], obj[3]))
2093 file.write("\t@echo $(CC) ... -o $@ $<\n")
2094 file.write("\t$(CC) -c $(CPU_OPT) -o $@ $<\n")
2095 # and .s depends on .S
2096 file.write("%s.s: %s\n" % (obj[3], source))
2097 file.write("\t@echo $(CPP) ... $< > $@\n")
2098 # Note: next 2 lines are ONE output line!
2099 file.write("\t$(CPP) $(CPPFLAGS) $< ")
2100 file.write(">$@.new && mv $@.new $@\n")
2102 file.write("%s: %s\n" % (obj[0], source))
2103 file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
2104 #file.write("%s\n" % objrule[2])
2106 for driverrule, driver in image.getdriverrules().items():
2107 source = topify(driver[1])
2108 file.write("%s: %s\n" % (driver[0], source))
2109 file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
2110 #file.write("%s\n" % objrule[2])
2112 # special rule for chip_target.c
2113 file.write("static.o: static.c\n")
2114 file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
2116 # Print out the rules that will make cause the files
2117 # generated by NLBConfig.py to be remade if any dependencies change.
2119 file.write("\n# Remember the automatically generated files\n")
2120 file.write("GENERATED:=\n")
2121 for genfile in ['Makefile',
2124 'LinuxBIOSDoc.config' ]:
2125 file.write("GENERATED += %s\n" % genfile)
2126 file.write("GENERATED += %s\n" % image.getincludefilename())
2128 keys = global_options_by_order
2130 file.write("\necho:\n")
2132 file.write("\t@echo %s='$(%s)'\n"% (key,key))
2134 for i, m in image.getmakerules().items():
2135 file.write("%s: " %i)
2136 for i in m.dependency:
2137 file.write("%s " % i)
2140 file.write("\t%s\n" % i)
2141 writemakefilefooter(file, makefilepath)
2145 def writemakefile(path):
2146 makefilepath = os.path.join(path, "Makefile")
2147 print "Creating", makefilepath
2148 file = safe_open(makefilepath, 'w+')
2149 writemakefileheader(file, makefilepath)
2152 file.write("\nall:")
2154 file.write(" %s" % i.name)
2156 file.write("include Makefile.settings\n\n")
2157 for i, o in romimages.items():
2158 file.write("%s/linuxbios.rom:\n" % o.getname())
2159 file.write("\tif (cd %s; \\\n" % o.getname())
2160 file.write("\t\tmake linuxbios.rom)\\\n")
2161 file.write("\tthen true; else exit 1; fi;\n\n")
2162 file.write("clean: ")
2163 for i in romimages.keys():
2164 file.write(" %s-clean" % i)
2166 for i, o in romimages.items():
2167 file.write("%s-clean:\n" % o.getname())
2168 file.write("\t(cd %s; make clean)\n\n" % o.getname())
2171 file.write("%s:" % i.name)
2173 file.write(" %s/linuxbios.rom " % j)
2175 file.write("\t cat ")
2177 file.write(" %s/linuxbios.rom " % j)
2178 file.write("> %s\n\n" %i.name)
2181 file.write(".PHONY: all clean")
2182 for i in romimages.keys():
2183 file.write(" %s-clean" % i)
2184 for i, o in romimages.items():
2185 file.write(" %s/linuxbios.rom" % o.getname())
2188 writemakefilefooter(file, makefilepath)
2191 def writeinitincludes(image):
2192 global include_pattern
2193 filepath = os.path.join(image.gettargetdir(), image.getincludefilename())
2194 print "Creating", filepath
2195 outfile = safe_open(filepath, 'w+')
2196 if (image.newformat()):
2197 infile = safe_open(image.getinitfile(), 'r')
2199 line = infile.readline()
2201 p = include_pattern.match(line)
2203 for i in image.getinitincludes():
2204 inc = image.getinitinclude(i)
2205 if (inc.getstring() == p.group(1)):
2206 outfile.write("#include \"%s\"\n" % inc.getpath())
2209 line = infile.readline()
2213 for i in image.getinitincludes():
2214 outfile.write("#include <%s>\n" % i)
2217 def writeldoptions(image):
2218 """Write ldoptions file."""
2219 filename = os.path.join(image.gettargetdir(), "ldoptions")
2220 print "Creating", filename
2221 file = safe_open(filename, 'w+')
2222 for o in global_exported_options:
2223 if (hasvalue(o.name, image) and IsInt(getoption(o.name, image))):
2224 file.write("%s = %s;\n" % (o.name, getformated(o.name, image)))
2225 for o in image.exported_options:
2226 if (not o in global_exported_options and hasvalue(o.name, image) and IsInt(getoption(o.name, image))):
2227 file.write("%s = %s;\n" % (o.name, getformated(o.name, image)))
2230 def dumptree(part, lvl):
2231 debug.info(debug.dumptree, "DUMPTREE ME is")
2233 # dump the siblings -- actually are there any? not sure
2235 debug.info(debug.dumptree, "DUMPTREE SIBLINGS are")
2236 kid = part.next_sibling
2239 kid = kid.next_sibling
2241 debug.info(debug.dumptree, "DUMPTREE KIDS are")
2242 #for kid in part.children:
2244 dumptree(part.children, lvl+1)
2245 kid = part.next_sibling
2248 dumptree(kid.children, lvl + 1)
2249 kid = kid.next_sibling
2250 debug.info(debug.dumptree, "DONE DUMPTREE")
2252 def writecode(image):
2253 filename = os.path.join(img_dir, "static.c")
2254 print "Creating", filename
2255 file = safe_open(filename, 'w+')
2256 file.write("#include <device/device.h>\n")
2257 file.write("#include <device/pci.h>\n")
2258 for path in image.getconfigincludes().values():
2259 file.write("#include \"%s\"\n" % path)
2260 gencode(image.getroot(), file, 0)
2261 gencode(image.getroot(), file, 1)
2264 def gencode(part, file, pass_num):
2265 debug.info(debug.gencode, "GENCODE ME is")
2266 part.gencode(file, pass_num)
2267 # dump the siblings -- actually are there any? not sure
2268 debug.info(debug.gencode, "GENCODE SIBLINGS are")
2269 kid = part.next_sibling
2271 kid.gencode(file, pass_num)
2272 kid = kid.next_sibling
2273 # now dump the children
2274 debug.info(debug.gencode, "GENCODE KIDS are")
2276 gencode(part.children, file, pass_num)
2277 kid = part.next_sibling
2280 gencode(kid.children, file, pass_num)
2281 kid = kid.next_sibling
2282 debug.info(debug.gencode, "DONE GENCODE")
2285 """Add any run-time checks to verify that parsing the configuration
2288 for image in romimages.values():
2289 print("Verifying ROMIMAGE %s" % image.name)
2290 if (image.newformat() and image.getinitfile() == ''):
2291 fatal("An init file must be specified")
2292 for op in image.exported_options:
2293 if (getoptionvalue(op.name, op, image) == 0 and getoptionvalue(op.name, op, 0) == 0):
2294 warning("Exported option %s has no value (check Options.lb)" % op.name);
2295 print("Verifing global options")
2296 for op in global_exported_options:
2297 if (getoptionvalue(op.name, op, 0) == 0):
2298 notice("Exported option %s has no value (check Options.lb)" % op.name);
2300 #=============================================================================
2302 #=============================================================================
2303 if __name__=='__main__':
2304 from sys import argv
2306 fatal("Args: <file> <path to linuxbios>")
2308 top_config_file = os.path.abspath(sys.argv[1])
2310 treetop = os.path.abspath(sys.argv[2])
2312 # Now read in the customizing script...
2314 fp = safe_open(argv[1], 'r')
2315 if (not parse('board', fp.read())):
2316 fatal("Could not parse file")
2321 # no longer need to check if an options has been used
2324 for image_name, image in romimages.items():
2325 if (debug.level(debug.dumptree)):
2326 debug.info(debug.dumptree, "DEVICE TREE:")
2327 dumptree(image.getroot(), 0)
2329 img_dir = image.gettargetdir()
2330 if not os.path.isdir(img_dir):
2331 print "Creating directory %s" % img_dir
2332 os.makedirs(img_dir)
2334 if (debug.level(debug.dump)):
2335 for i in image.getinitincludes():
2336 debug.info(debug.dump, "crt0include file %s" % i)
2337 for i in image.getdriverrules().keys():
2338 debug.info(debug.dump, "driver file %s" % i)
2339 for i in image.getldscripts():
2340 debug.info(debug.dump, "ldscript file %s" % i)
2341 for i, m in image.getmakerules().items():
2342 debug.info(debug.dump, " makerule %s dep %s act %s" % (i, m.dependency, m.actions))
2345 writeimagesettings(image)
2346 writeinitincludes(image)
2347 writeimagemakefile(image)
2348 writeldoptions(image)
2350 writemakefilesettings(target_dir)
2351 writemakefile(target_dir)