14 full_mainboard_path = ''
19 # -----------------------------------------------------------------------------
21 # -----------------------------------------------------------------------------
24 """Used to keep track of the current part or dir"""
26 def __init__ (self, stack):
35 if (self.index < self.len):
36 s = self.stack[self.index]
37 self.index = self.index + 1
45 return len(self.stack)
47 def __getitem__ (self, i):
51 return self.__stack_iter(self.stack)
54 self.stack.append(part)
58 return self.stack.pop()
69 return (len(self.stack) == 0)
82 def __init__(self, *level):
85 def setdebug(self, *level):
88 def level(self, level):
89 return level in self.__level
91 def info(self, level, str):
92 if level in self.__level:
96 debug = debug_info(debug_info.none)
97 #debug = debug_info(debug_info.dumptree)
98 #debug = debug_info(debug_info.object)
99 #debug = debug_info(debug_info.gencode)
101 # -----------------------------------------------------------------------------
103 # -----------------------------------------------------------------------------
106 """Print error message"""
109 print "===> ERROR: %s" % string
112 """Print error message and exit"""
117 """Print warning message"""
119 warnings = warnings + 1
120 print "===> WARNING: %s" % string
123 """Exit parser if an error has been encountered"""
127 def safe_open(file, mode):
129 return open(file, mode)
131 fatal("Could not open file \"%s\"" % file)
133 # -----------------------------------------------------------------------------
135 # -----------------------------------------------------------------------------
138 """A rom image is the ultimate goal of coreboot"""
139 def __init__ (self, name):
140 # name of this rom image
143 # instance counter for parts
144 self.partinstance = 0
146 # chip config files included by the 'config' directive
147 self.configincludes = {}
158 def addconfiginclude(self, part, path):
159 setdict(self.configincludes, part, path)
161 def getconfigincludes(self):
162 return self.configincludes
164 def getincludefilename(self):
165 if (self.useinitincludes):
168 return "crt0_includes.h"
171 return self.useinitincludes
174 return self.partinstance
176 def newpartinstance(self):
177 i = self.partinstance
178 self.partinstance = self.partinstance + 1
181 def setroot(self, part):
188 """A configuration part"""
189 def __init__ (self, image, dir, parent, part, type_name, instance_name, chip_or_device):
191 debug.info(debug.object, "partobj dir %s parent %s part %s" \
192 % (dir, parent.instance_name, part))
194 debug.info(debug.object, "partobj dir %s part %s" \
197 # romimage that is configuring this part
200 # links for static device tree
202 self.prev_sibling = 0
203 self.next_sibling = 0
206 self.chip_or_device = chip_or_device
208 # initializers for static device tree
209 self.registercode = {}
214 # type name of this part
215 self.type_name = type_name
217 # directory containing part files
220 # instance number, used to distinguish anonymous
221 # instances of this part
222 self.instance = image.newpartinstance()
223 debug.info(debug.object, "INSTANCE %d" % self.instance)
225 # Name of chip config file (0 if not needed)
228 # Flag to indicate that we have generated type
229 # definitions for this part (only want to do it once)
235 # Resources of the device
239 # Enabled state of the device
242 # Flag if I am a duplicate device
245 # If there is a chip.h file, we will create an
248 chiph = os.path.join(dir, "chip.h")
249 if (os.path.exists(chiph)):
250 debug.info(debug.object, "%s has chip at %s" % (self, dir))
251 self.addconfig(chiph)
253 # If no instance name is supplied then generate
255 if (instance_name == 0):
256 self.instance_name = self.type_name + \
257 "_dev%d" % self.instance
258 self.chipinfo_name = "%s_info_%d" \
259 % (self.type_name, self.instance)
261 self.instance_name = instance_name
262 self.chipinfo_name = "%s_info_%d" % (self.instance_name, self.instance)
264 # Link this part into the device list
265 if (self.chip_or_device == 'device'):
266 if (image.last_device):
267 image.last_device.next_device = self
268 self.prev_device = image.last_device
269 image.last_device = self
271 # Link this part into the tree
272 if (parent and (part != 'arch')):
273 debug.info(debug.gencode, "add to parent")
275 # add current child as my sibling,
277 if (parent.children):
278 debug.info(debug.gencode, "add %s (%d) as sibling" % (parent.children.dir, parent.children.instance))
279 youngest = parent.children
280 while(youngest.next_sibling):
281 youngest = youngest.next_sibling
282 youngest.next_sibling = self
283 self.prev_sibling = youngest
285 parent.children = self
290 return "%s: %s" % (self.part, self.type)
292 return self.chip_or_device
294 def readable_name(self):
296 name = "%s_%d" % (self.type_name, self.instance)
297 if (self.chip_or_device == 'chip'):
298 name = "%s %s %s" % (name, self.part, self.dir)
300 name = "%s %s" % (name, self.path)
303 def graph_name(self):
304 name = "{ {_dev%d|" % self.instance
306 name = "%s%s" % (name, self.part)
308 name = "%s%s" % (name, self.chip_or_device)
310 name = "%s}|%s}" % (name, self.type_name)
312 name = "%s}|%s}" % (name, self.parent.type_name)
315 def dumpme(self, lvl):
316 """Dump information about this part for debugging"""
317 print "%d: %s" % (lvl, self.readable_name())
318 print "%d: part %s" % (lvl, self.part)
319 print "%d: instance %d" % (lvl, self.instance)
320 print "%d: chip_or_device %s" % (lvl, self.chip_or_device)
321 print "%d: dir %s" % (lvl,self.dir)
322 print "%d: type_name %s" % (lvl,self.type_name)
323 print "%d: parent: %s" % (lvl, self.parent.readable_name())
325 print "%d: child %s" % (lvl, self.children.readable_name())
326 if (self.next_sibling):
327 print "%d: siblings %s" % (lvl, self.next_sibling.readable_name())
328 print "%d: registercode " % lvl
329 for f, v in self.registercode.items():
330 print "\t%s = %s" % (f, v)
331 print "%d: chipconfig %s" % (lvl, self.chipconfig)
334 def firstchilddevice(self):
335 """Find the first device in the children link."""
338 if (kid.chip_or_device == 'device'):
344 def firstparentdevice(self):
345 """Find the first device in the parent link."""
347 while (parent and (parent.parent != parent) and (parent.chip_or_device != 'device')):
348 parent = parent.parent
349 if ((parent.parent != parent) and (parent.chip_or_device != 'device')):
351 while(parent and (parent.dup == 1)):
352 parent = parent.prev_sibling
354 fatal("Device %s has no device parent; this is a config file error" % self.readable_name())
357 def firstparentdevicelink(self):
358 """Find the first device in the parent link and record which link it is."""
361 while (parent and (parent.parent != parent) and (parent.chip_or_device != 'device')):
362 parent = parent.parent
363 if ((parent.parent != parent) and (parent.chip_or_device != 'device')):
365 while(parent and (parent.dup == 1)):
366 parent = parent.prev_sibling
369 fatal("Device %s has no device parent; this is a config file error" % self.readable_name())
373 def firstparentchip(self):
374 """Find the first chip in the parent link."""
377 if ((parent.parent == parent) or (parent.chip_or_device == 'chip')):
380 parent = parent.parent
381 fatal("Device %s has no chip parent; this is a config file error" % self.readable_name())
383 def firstsiblingdevice(self):
384 """Find the first device in the sibling link."""
385 sibling = self.next_sibling
386 while(sibling and (sibling.path == self.path)):
387 sibling = sibling.next_sibling
388 if ((not sibling) and (self.parent.chip_or_device == 'chip')):
389 sibling = self.parent.next_sibling
391 if (sibling.chip_or_device == 'device'):
394 sibling = sibling.children
397 def gencode(self, file, pass_num):
398 """Generate static initalizer code for this part. Two passes
399 are used - the first generates type information, and the second
400 generates instance information"""
402 if (self.chip_or_device == 'chip'):
406 file.write("struct device %s;\n" \
407 % self.instance_name)
409 file.write("struct device dev_root;\n")
411 # This is pass the second, which is pass number 1
412 # this is really just a case statement ...
414 if (self.chip_or_device == 'chip'):
415 if (self.chipconfig):
416 debug.info(debug.gencode, "gencode: chipconfig(%d)" % \
418 file.write("struct %s_config %s" % (self.type_name ,\
420 if (self.registercode):
421 file.write("\t= {\n")
422 for f, v in self.registercode.items():
423 file.write( "\t.%s = %s,\n" % (f, v))
429 if (self.instance == 0):
430 self.instance_name = "dev_root"
431 file.write("struct device **last_dev_p = &%s.next;\n" % (self.image.last_device.instance_name))
432 file.write("struct device dev_root = {\n")
433 file.write("\t.ops = &default_dev_ops_root,\n")
434 file.write("\t.bus = &dev_root.link[0],\n")
435 file.write("\t.path = { .type = DEVICE_PATH_ROOT },\n")
436 file.write("\t.enabled = 1,\n\t.links = 1,\n")
437 file.write("\t.on_mainboard = 1,\n")
438 file.write("\t.link = {\n\t\t[0] = {\n")
439 file.write("\t\t\t.dev=&dev_root,\n\t\t\t.link = 0,\n")
440 file.write("\t\t\t.children = &%s,\n" % self.firstchilddevice().instance_name)
441 file.write("\t\t},\n")
443 if (self.chipconfig):
444 file.write("\t.chip_ops = &%s_ops,\n" % self.type_name)
445 file.write("\t.chip_info = &%s_info_%s,\n" % (self.type_name, self.instance))
446 file.write("\t.next = &%s,\n" % self.firstchilddevice().instance_name)
450 # Don't print duplicate devices, just print their children
454 file.write("struct device %s = {\n" % self.instance_name)
455 file.write("\t.ops = 0,\n")
456 file.write("\t.bus = &%s.link[%d],\n" % \
457 (self.firstparentdevice().instance_name, \
458 self.firstparentdevicelink()))
459 file.write("\t.path = {%s},\n" % self.path)
460 file.write("\t.enabled = %d,\n" % self.enabled)
461 file.write("\t.on_mainboard = 1,\n")
463 file.write("\t.resources = %d,\n" % self.resources)
464 file.write("\t.resource = {%s\n\t },\n" % self.resource)
465 file.write("\t.link = {\n");
468 while(bus and (bus.path == self.path)):
469 child = bus.firstchilddevice()
470 if (child or (bus != self) or (bus.next_sibling and (bus.next_sibling.path == self.path))):
471 file.write("\t\t[%d] = {\n" % links)
472 file.write("\t\t\t.link = %d,\n" % links)
473 file.write("\t\t\t.dev = &%s,\n" % self.instance_name)
475 file.write("\t\t\t.children = &%s,\n" %child.instance_name)
476 file.write("\t\t},\n")
479 bus = bus.next_sibling
483 file.write("\t.links = %d,\n" % (links))
484 sibling = self.firstsiblingdevice();
486 file.write("\t.sibling = &%s,\n" % sibling.instance_name)
487 chip = self.firstparentchip()
488 if (chip and chip.chipconfig):
489 file.write("\t.chip_ops = &%s_ops,\n" % chip.type_name)
490 file.write("\t.chip_info = &%s_info_%s,\n" % (chip.type_name, chip.instance))
491 if (self.next_device):
492 file.write("\t.next=&%s\n" % self.next_device.instance_name)
496 def addconfig(self, path):
497 """Add chip config file to this part"""
498 self.chipconfig = os.path.join(self.dir, path)
499 self.image.addconfiginclude(self.type_name, self.chipconfig)
501 def addregister(self, field, value):
502 """Register static initialization information"""
503 if (self.chip_or_device != 'chip'):
504 fatal("Only chips can have register values")
505 field = dequote(field)
506 value = dequote(value)
507 setdict(self.registercode, field, value)
509 def set_enabled(self, enabled):
510 self.enabled = enabled
512 def start_resources(self):
516 def end_resources(self):
517 self.resource = "%s" % (self.resource)
519 def add_resource(self, type, index, value):
520 """ Add a resource to a device """
521 self.resource = "%s\n\t\t{ .flags=%s, .index=0x%x, .base=0x%x}," % (self.resource, type, index, value)
522 self.resources = self.resources + 1
524 def set_path(self, path):
526 if (self.prev_sibling and (self.prev_sibling.path == self.path)):
528 if (self.prev_device):
529 self.prev_device.next_device = self.next_device
530 if (self.next_device):
531 self.next_device.prev_device = self.prev_device
532 if (self.image.last_device == self):
533 self.image.last_device = self.prev_device
537 def addpcipath(self, slot, function):
538 """ Add a relative pci style path from our parent to this device """
539 if ((slot < 0) or (slot > 0x1f)):
540 fatal("Invalid device id")
541 if ((function < 0) or (function > 7)):
542 fatal("Invalid pci function %s" % function )
543 self.set_path(".type=DEVICE_PATH_PCI,{.pci={ .devfn = PCI_DEVFN(0x%x,%d)}}" % (slot, function))
545 def addpnppath(self, port, device):
546 """ Add a relative path to a pnp device hanging off our parent """
547 if ((port < 0) or (port > 65536)):
548 fatal("Invalid port")
549 if ((device < 0) or (device > 0xffff)):
550 fatal("Invalid device")
551 self.set_path(".type=DEVICE_PATH_PNP,{.pnp={ .port = 0x%x, .device = 0x%x }}" % (port, device))
553 def addi2cpath(self, device):
554 """ Add a relative path to a i2c device hanging off our parent """
555 if ((device < 0) or (device > 0x7f)):
556 fatal("Invalid device")
557 self.set_path(".type=DEVICE_PATH_I2C,{.i2c={ .device = 0x%x }}" % (device))
559 def addapicpath(self, apic_id):
560 """ Add a relative path to a cpu device hanging off our parent """
561 if ((apic_id < 0) or (apic_id > 255)):
562 fatal("Invalid device")
563 self.set_path(".type=DEVICE_PATH_APIC,{.apic={ .apic_id = 0x%x }}" % (apic_id))
565 def addpci_domainpath(self, pci_domain):
566 """ Add a pci_domain number to a chip """
567 if ((pci_domain < 0) or (pci_domain > 0xffff)):
568 fatal("Invalid pci_domain: 0x%x is out of the range 0 to 0xffff" % pci_domain)
569 self.set_path(".type=DEVICE_PATH_PCI_DOMAIN,{.pci_domain={ .domain = 0x%x }}" % (pci_domain))
571 def addapic_clusterpath(self, cluster):
572 """ Add an apic cluster to a chip """
573 if ((cluster < 0) or (cluster > 15)):
574 fatal("Invalid apic cluster: %d is out of the range 0 to ff" % cluster)
575 self.set_path(".type=DEVICE_PATH_APIC_CLUSTER,{.apic_cluster={ .cluster = 0x%x }}" % (cluster))
577 def addcpupath(self, cpu_id):
578 """ Add a relative path to a cpu device hanging off our parent """
579 if ((cpu_id < 0) or (cpu_id > 255)):
580 fatal("Invalid device")
581 self.set_path(".type=DEVICE_PATH_CPU,{.cpu={ .id = 0x%x }}" % (cpu_id))
584 def addcpu_buspath(self, id):
585 """ Add a cpu_bus to a chip """
586 if ((id < 0) or (id > 255)):
587 fatal("Invalid device")
588 self.set_path(".type=DEVICE_PATH_CPU_BUS,{.cpu_bus={ .id = 0x%x }}" % (id))
591 # -----------------------------------------------------------------------------
593 # -----------------------------------------------------------------------------
595 def getdict(dict, name):
596 if name not in dict.keys():
597 debug.info(debug.dict, "Undefined: %s" % name)
599 v = dict.get(name, 0)
600 debug.info(debug.dict, "getdict %s returning %s" % (name, v))
603 def setdict(dict, name, value):
604 debug.info(debug.dict, "setdict sets %s to %s" % (name, value))
605 if name in dict.keys():
606 print "Duplicate in dict: %s" % name
612 curpart = partstack.tos()
613 curpart.addconfig(path)
615 def addregister(field, value):
617 curpart = partstack.tos()
618 curpart.addregister(field, value)
620 def devicepart(type):
621 global curimage, partstack
622 newpart = partobj(curimage, 0, partstack.tos(), type, \
624 #print "Configuring PART %s" % (type)
625 partstack.push(newpart)
626 #print " new PART tos is now %s\n" %partstack.tos().info()
627 # just push TOS, so that we can pop later.
629 def part(type, path, file, name):
630 global curimage, partstack
631 partdir = os.path.join(type, path)
632 srcdir = os.path.join(treetop, 'src')
633 fulldir = os.path.join(srcdir, partdir)
634 type_name = flatten_name(partdir)
635 #print "PART(%s, %s, %s, %s)\n" % (type, path, file, name)
636 newpart = partobj(curimage, fulldir, partstack.tos(), type, \
637 type_name, name, 'chip')
638 #print "Configuring PART %s, path %s" % (type, path)
639 partstack.push(newpart)
643 curpart = partstack.tos()
645 fatal("Trying to pop non-existent part")
646 #print "End PART %s" % curpart.part
647 oldpart = partstack.pop()
648 #print "partstack.pop, TOS is now %s\n" % oldpart.info()
650 #=============================================================================
652 #=============================================================================
654 a = re.sub("^\"", "", str)
655 a = re.sub("\"$", "", a)
656 # highly un-intuitive, need four \!
657 a = re.sub("\\\\\"", "\"", a)
660 def flatten_name(str):
661 a = re.sub("[/-]", "_", str)
668 # less general tokens should come first, otherwise they get matched
670 token COMMENT: 'comment'
672 token CPU_BUS: 'cpu_bus'
674 token DEVICE: 'device'
675 token DEVICE_ID: 'device_id'
680 token FORMAT: 'format'
688 token REGISTER: 'register'
689 token VENDOR_ID: 'vendor_id'
692 token HEX_NUM: '[0-9a-fA-F]+'
693 token HEX_PREFIX: '0x'
694 # Why is path separate? Because paths to resources have to at least
695 # have a slash, we thinks
696 token PATH: r'[-a-zA-Z0-9_.][-a-zA-Z0-9/_.]+[-a-zA-Z0-9_.]+'
697 # Dir's on the other hand are abitrary
698 # this may all be stupid.
699 token RULE: r'[-a-zA-Z0-9_$()./]+[-a-zA-Z0-9_ $()./]+[-a-zA-Z0-9_$()./]+'
700 token ID: r'[a-zA-Z_.]+[a-zA-Z0-9_.]*'
701 token STR: r'"([^\\"]+|\\.)*"'
709 token APIC_CLUSTER: 'apic_cluster'
711 token CPU_BUS: 'cpu_bus'
712 token PCI_DOMAIN: 'pci_domain'
715 rule expr: logical {{ l = logical }}
716 ( "&&" logical {{ l = l and logical }}
717 | "[|][|]" logical {{ l = l or logical }}
720 rule logical: factor {{ n = factor }}
721 ( "[+]" factor {{ n = n+factor }}
722 | "-" factor {{ n = n-factor }}
725 rule factor: term {{ v = term }}
726 ( "[*]" term {{ v = v*term }}
727 | "/" term {{ v = v/term }}
728 | "<<" term {{ v = v << term }}
729 | ">=" term {{ v = (v < term)}}
732 # A term is a number, variable, or an expression surrounded by parentheses
733 rule term: NUM {{ return long(NUM, 10) }}
734 | HEX_PREFIX HEX_NUM {{ return long(HEX_NUM, 16) }}
735 | ID {{ return lookup(ID) }}
736 | unop {{ return unop }}
737 | "\\(" expr "\\)" {{ return expr }}
739 rule unop: "!" expr {{ return not(expr) }}
741 rule partend<<C>>: (stmt<<C>>)* END {{ if (C): partpop()}}
743 # This is needed because the legacy cpu command could not distinguish
744 # between cpu vendors. It should just be PATH, but getting this change
745 # into the source tree will be tricky...
746 # DO NOT USE ID AS IT MAY GO AWAY IN THE FUTURE
747 rule partid: ID {{ return ID }}
748 | PATH {{ return PATH }}
750 rule parttype: CHIP {{ return '' }}
752 rule partdef<<C>>: {{ name = 0 }}
754 [ STR {{ name = dequote(STR) }}
755 ] {{ if (C): part(parttype, partid, 'Config.lb', name) }}
758 rule field: STR {{ return STR }}
760 rule register<<C>>: REGISTER field '=' STR {{ if (C): addregister(field, STR) }}
762 rule enable<<C>>: {{ val = 1 }}
765 ) {{ if(C): partstack.tos().set_enabled(val) }}
767 rule resource<<C>>: {{ type = "" }}
768 ( IO {{ type = "IORESOURCE_FIXED | IORESOURCE_ASSIGNED | IORESOURCE_IO" }}
769 | MEM {{ type = "IORESOURCE_FIXED | IORESOURCE_ASSIGNED | IORESOURCE_MEM" }}
770 | IRQ {{ type = "IORESOURCE_FIXED | IORESOURCE_ASSIGNED | IORESOURCE_IRQ" }}
771 | DRQ {{ type = "IORESOURCE_FIXED | IORESOURCE_ASSIGNED | IORESOURCE_DRQ" }}
773 term '=' {{ index = term }}
774 term {{ value = term }}
775 {{ if (C): partstack.tos().add_resource(type, index, value) }}
778 rule resources<<C>>: {{ if (C): partstack.tos().start_resources() }}
780 {{ if (C): partstack.tos().end_resources() }}
783 rule pci<<C>>: PCI {{ if (C): devicepart('pci') }}
785 HEX_NUM {{ slot = int(HEX_NUM,16) }}
786 '.' HEX_NUM {{ function = int(HEX_NUM, 16) }}
787 {{ if (C): partstack.tos().addpcipath(slot, function) }}
788 rule pci_domain<<C>>:
789 PCI_DOMAIN {{ if (C): devicepart('pci_domain') }}
790 HEX_NUM {{ pci_domain = int(HEX_NUM, 16) }}
791 {{ if (C): partstack.tos().addpci_domainpath(pci_domain) }}
793 rule pnp<<C>>: PNP {{ if (C): devicepart('pnp') }}
794 HEX_NUM {{ port = int(HEX_NUM,16) }}
795 '.' HEX_NUM {{ device = int(HEX_NUM, 16) }}
796 {{ if (C): partstack.tos().addpnppath(port, device) }}
798 rule i2c<<C>>: I2C {{ if (C): devicepart('i2c') }}
799 HEX_NUM {{ device = int(HEX_NUM, 16) }}
800 {{ if (C): partstack.tos().addi2cpath(device) }}
802 rule apic<<C>>: APIC {{ if (C): devicepart('apic') }}
803 HEX_NUM {{ apic_id = int(HEX_NUM, 16) }}
804 {{ if (C): partstack.tos().addapicpath(apic_id) }}
806 rule apic_cluster<<C>>: APIC_CLUSTER {{ if (C): devicepart('apic_cluster') }}
807 HEX_NUM {{ cluster = int(HEX_NUM, 16) }}
808 {{ if (C): partstack.tos().addapic_clusterpath(cluster) }}
810 rule cpu<<C>>: CPU {{ if (C): devicepart('cpu') }}
811 HEX_NUM {{ id = int(HEX_NUM, 16) }}
812 {{ if (C): partstack.tos().addcpupath(id) }}
814 rule cpu_bus<<C>>: CPU_BUS {{ if (C): devicepart('cpu_bus') }}
815 HEX_NUM {{ id = int(HEX_NUM, 16) }}
816 {{ if (C): partstack.tos().addcpu_buspath(id) }}
819 pci<<C>> {{ return pci }}
820 | pci_domain<<C>> {{ return pci_domain }}
821 | pnp<<C>> {{ return pnp }}
822 | i2c<<C>> {{ return i2c }}
823 | apic<<C>> {{ return apic }}
824 | apic_cluster<<C>> {{ return apic_cluster }}
825 | cpu<<C>> {{ return cpu }}
826 | cpu_bus<<C>> {{ return cpu_bus }}
828 rule prtval: expr {{ return str(expr) }}
829 | STR {{ return STR }}
831 rule prtlist: prtval {{ el = "%(" + prtval }}
832 ( "," prtval {{ el = el + "," + prtval }}
833 )* {{ return el + ")" }}
835 rule prtstmt<<C>>: PRINT STR {{ val = STR }}
836 [ "," prtlist {{ val = val + prtlist }}
837 ] {{ if (C): print eval(val) }}
839 rule device<<C>>: DEVICE dev_path<<C>>
845 partdef<<C>> {{ return partdef }}
846 | prtstmt<<C>> {{ return prtstmt }}
847 | register<<C>> {{ return register }}
848 | device<<C>> {{ return device }}
850 rule value: STR {{ return dequote(STR) }}
851 | expr {{ return expr }}
853 rule devicetree: partdef<<1>>
856 rule wrstr<<ID>>: STR {{ setwrite(ID, dequote(STR)) }}
860 #=============================================================================
862 #=============================================================================
864 def dumptree(part, lvl):
865 debug.info(debug.dumptree, "DUMPTREE ME is")
868 # dump the siblings -- actually are there any? not sure
870 debug.info(debug.dumptree, "DUMPTREE SIBLINGS are")
871 kid = part.next_sibling
874 kid = kid.next_sibling
876 debug.info(debug.dumptree, "DUMPTREE KIDS are")
877 #for kid in part.children:
879 dumptree(part.children, lvl+1)
880 kid = part.next_sibling
883 dumptree(kid.children, lvl + 1)
884 kid = kid.next_sibling
885 debug.info(debug.dumptree, "DONE DUMPTREE")
887 def writecode(image):
888 filename = os.path.join(img_dir, "static.c")
889 print " SCONFIG Creating", os.path.basename(filename)
890 file = safe_open(filename, 'w+')
891 file.write("#include <device/device.h>\n")
892 file.write("#include <device/pci.h>\n")
893 for path in image.getconfigincludes().values():
894 file.write("#include \"%s\"\n" % path)
895 file.write("\n/* pass 0 */\n")
896 gencode(image.getroot(), file, 0)
897 file.write("\n/* pass 1 */\n")
898 gencode(image.getroot(), file, 1)
901 def gencode(part, file, pass_num):
902 debug.info(debug.gencode, "GENCODE ME is")
903 part.gencode(file, pass_num)
904 # dump the siblings -- actually are there any? not sure
905 debug.info(debug.gencode, "GENCODE SIBLINGS are")
906 kid = part.next_sibling
908 kid.gencode(file, pass_num)
909 kid = kid.next_sibling
910 # now dump the children
911 debug.info(debug.gencode, "GENCODE KIDS are")
913 gencode(part.children, file, pass_num)
914 kid = part.next_sibling
917 gencode(kid.children, file, pass_num)
918 kid = kid.next_sibling
919 debug.info(debug.gencode, "DONE GENCODE")
921 def writegraph(image):
922 filename = os.path.join(img_dir, "static.dot")
923 print " SCONFIG Creating", os.path.basename(filename)
924 file = safe_open(filename, 'w+')
925 file.write("digraph devicetree {\n")
926 file.write(" rankdir=LR\n")
927 genranks(image.getroot(), file, 0)
928 gennodes(image.getroot(), file)
929 gengraph(image.getroot(), file)
933 def genranks(part, file, level):
934 #file.write(" # Level %d\n" % level )
935 file.write(" { rank = same; \"dev_%s_%d\"" % (part.type_name,part.instance ))
936 sib = part.next_sibling
938 file.write("; \"dev_%s_%d\"" % (sib.type_name, sib.instance))
939 sib = sib.next_sibling
941 # now dump the children
943 genranks(part.children, file, level + 1)
945 kid = part.next_sibling
948 genranks(kid.children, file, level + 1)
949 kid = kid.next_sibling
952 def gennodes(part, file):
953 file.write(" dev_%s_%d[shape=record, label=\"%s\"];\n" % (part.type_name,part.instance,part.graph_name() ))
954 sib = part.next_sibling
956 file.write(" dev_%s_%d[shape=record, label=\"%s\"];\n" % (sib.type_name,sib.instance,sib.graph_name() ))
957 sib = sib.next_sibling
958 # now dump the children
960 gennodes(part.children, file)
962 kid = part.next_sibling
965 gennodes(kid.children, file)
966 kid = kid.next_sibling
969 def gengraph(part, file):
970 if (part.parent != part):
971 file.write(" dev_%s_%d -> dev_%s_%d;\n" % \
972 (part.parent.type_name, part.parent.instance, \
973 part.type_name, part.instance ))
974 sib = part.next_sibling
976 file.write(" dev_%s_%d -> dev_%s_%d;\n" % \
977 (sib.parent.type_name, sib.parent.instance, \
978 sib.type_name, sib.instance ))
979 sib = sib.next_sibling
981 kid = part.next_sibling
984 gengraph(kid.children, file)
985 kid = kid.next_sibling
988 gengraph(part.children, file)
990 #=============================================================================
992 #=============================================================================
993 if __name__=='__main__':
996 fatal("Args: <file> <path to coreboot> <output-dir>")
998 file = "devicetree.cb"
999 partdir = os.path.join("mainboard", sys.argv[1])
1001 srcdir = os.path.join(treetop, 'src')
1002 fulldir = os.path.join(srcdir, partdir)
1003 type_name = flatten_name(partdir)
1004 config_file = os.path.join(fulldir, file)
1006 curimage = romimage("new")
1009 newpart = partobj(curimage, fulldir, partstack.tos(), 'mainboard', \
1010 'mainboard', 0, 'chip')
1011 #print "Configuring PART %s, path %s" % (type, path)
1012 image.setroot(newpart);
1013 partstack.push(newpart)
1015 fp = safe_open(config_file, 'r')
1016 if (not parse('devicetree', fp.read())):
1017 fatal("Could not parse file")
1022 #debug.info(debug.dumptree, "DEVICE TREE:")
1023 #dumptree(curimage.getroot(), 0)