coreboot-kgpe-d16/util/showdevicetree/showdt.c

166 lines
4.2 KiB
C

/* Compile and dump the device tree */
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <stdio.h>
/* you can't include string.h due to conflicts with coreboot prototypes. */
void *memcpy(void *m1, void *m2, size_t s);
struct device_operations default_dev_ops_root = {
.read_resources = NULL,
.set_resources = NULL,
.enable_resources = NULL,
.init = NULL,
.scan_bus = NULL,
.reset_bus = NULL,
};
extern struct device dev_root;
struct device *all_devices = &dev_root;
const char mainboard_name[] = "showdt";
/*
* Warning: This function uses a static buffer. Don't call it more than once
* from the same print statement!
*/
const char *dev_path(device_t dev)
{
static char buffer[DEVICE_PATH_MAX];
buffer[0] = '\0';
if (!dev) {
memcpy(buffer, "<null>", 7);
} else {
switch(dev->path.type) {
case DEVICE_PATH_ROOT:
memcpy(buffer, "Root Device", 12);
break;
case DEVICE_PATH_PCI:
#if CONFIG_PCI_BUS_SEGN_BITS
sprintf(buffer, "PCI: %04x:%02x:%02x.%01x",
dev->bus->secondary >> 8,
dev->bus->secondary & 0xff,
PCI_SLOT(dev->path.pci.devfn),
PCI_FUNC(dev->path.pci.devfn));
#else
sprintf(buffer, "PCI: %02x:%02x.%01x",
dev->bus->secondary,
PCI_SLOT(dev->path.pci.devfn),
PCI_FUNC(dev->path.pci.devfn));
#endif
break;
case DEVICE_PATH_PNP:
sprintf(buffer, "PNP: %04x.%01x",
dev->path.pnp.port, dev->path.pnp.device);
break;
case DEVICE_PATH_I2C:
sprintf(buffer, "I2C: %02x:%02x",
dev->bus->secondary,
dev->path.i2c.device);
break;
case DEVICE_PATH_APIC:
sprintf(buffer, "APIC: %02x",
dev->path.apic.apic_id);
break;
case DEVICE_PATH_IOAPIC:
sprintf(buffer, "IOAPIC: %02x",
dev->path.ioapic.ioapic_id);
break;
case DEVICE_PATH_DOMAIN:
sprintf(buffer, "DOMAIN: %04x",
dev->path.domain.domain);
break;
case DEVICE_PATH_CPU_CLUSTER:
sprintf(buffer, "CPU_CLUSTER: %01x",
dev->path.cpu_cluster.cluster);
break;
case DEVICE_PATH_CPU:
sprintf(buffer, "CPU: %02x", dev->path.cpu.id);
break;
case DEVICE_PATH_CPU_BUS:
sprintf(buffer, "CPU_BUS: %02x", dev->path.cpu_bus.id);
break;
case DEVICE_PATH_MMIO:
sprintf(buffer, "MMIO: %08x", dev->path.mmio.addr);
break;
default:
printf("Unknown device path type: %d\n",
dev->path.type);
break;
}
}
return buffer;
}
void show_devs_tree(struct device *dev, int debug_level, int depth, int linknum)
{
char depth_str[20] = "";
int i;
struct device *sibling;
struct bus *link;
for (i = 0; i < depth; i++)
depth_str[i] = ' ';
depth_str[i] = '\0';
printf("%s%s: enabled %d%s\n",
depth_str, dev_path(dev), dev->enabled,
dev->chip_ops ? ":has a chip":"");
for (link = dev->link_list; link; link = link->next) {
for (sibling = link->children; sibling;
sibling = sibling->sibling)
show_devs_tree(sibling, debug_level, depth + 1, i);
}
}
void show_all_devs_tree(int debug_level, const char *msg)
{
printf("Show all devs in tree form...%s\n", msg);
show_devs_tree(all_devices, debug_level, 0, -1);
}
void show_devs_subtree(struct device *root, int debug_level, const char *msg)
{
printf("Show all devs in subtree %s...%s\n",
dev_path(root), msg);
printf("%s\n", msg);
show_devs_tree(root, debug_level, 0, -1);
}
void show_all_devs(int debug_level, const char *msg)
{
struct device *dev;
printf("Show all devs...%s\n", msg);
for (dev = all_devices; dev; dev = dev->next) {
printf("%s: enabled %d%s\n",
dev_path(dev), dev->enabled,
dev->chip_ops ? ":has a chip":"");
}
}
main()
{
show_all_devs(1, "");
show_all_devs_tree(1, "");
}
/*
* Example: (yank this and paste into M-x compile in emacs)
* or tail -2 showdt.c | head -1 |sh
* or whatever.
cc -I ../src -I ../src/include -I ../src/arch/arm/include/ -include build/mainboard/google/snow/static.c showdt.c
*/