Skip to content

Commit

Permalink
device/device.h: Drop multiple links
Browse files Browse the repository at this point in the history
Multiple links are unused throughout the tree and make the code more
confusing as an iteration over all busses is needed to get downstream
devices. This also not done consistently e.g. the allocator does not
care about multiple links on busses. A better way of dealing multiple
links below a device is to feature dummy devices with each their
respective bus.

This drops the sconfig capability to declare the same device multiple
times which was previously used to declare multiple links.

Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
Change-Id: Iab6fe269faef46ae77ed1ea425440cf5c7dbd49b
Reviewed-on: https://review.coreboot.org/c/coreboot/+/78328
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Jincheng Li <jincheng.li@intel.com>
Reviewed-by: Lean Sheng Tan <sheng.tan@9elements.com>
  • Loading branch information
ArthurHeymans authored and felixheld committed Jan 29, 2024
1 parent 27ce0ec commit 80c79a5
Show file tree
Hide file tree
Showing 16 changed files with 186 additions and 354 deletions.
83 changes: 40 additions & 43 deletions src/arch/x86/mpspec.c
Original file line number Diff line number Diff line change
Expand Up @@ -282,48 +282,46 @@ void smp_write_intsrc_pci_bridge(struct mp_config_table *mc,
int srcbus;
int slot;

struct bus *link;
unsigned char dstirq_x[4];

for (link = dev->link_list; link; link = link->next) {
if (!dev->link_list)
return;

child = link->children;
srcbus = link->secondary;
child = dev->link_list->children;
srcbus = dev->link_list->secondary;

while (child) {
if (child->path.type != DEVICE_PATH_PCI)
goto next;
while (child) {
if (child->path.type != DEVICE_PATH_PCI)
goto next;

slot = (child->path.pci.devfn >> 3);
/* round pins */
for (i = 0; i < 4; i++)
dstirq_x[i] = dstirq[(i + slot) % 4];

if ((child->class >> 16) != PCI_BASE_CLASS_BRIDGE) {
/* pci device */
printk(BIOS_DEBUG, "route irq: %s\n",
dev_path(child));
for (i = 0; i < 4; i++)
smp_write_intsrc(mc, irqtype, irqflag,
srcbus, (slot<<2)|i, dstapic,
dstirq_x[i]);
goto next;
}
slot = (child->path.pci.devfn >> 3);
/* round pins */
for (i = 0; i < 4; i++)
dstirq_x[i] = dstirq[(i + slot) % 4];

switch (child->class>>8) {
case PCI_CLASS_BRIDGE_PCI:
case PCI_CLASS_BRIDGE_PCMCIA:
case PCI_CLASS_BRIDGE_CARDBUS:
printk(BIOS_DEBUG, "route irq bridge: %s\n",
dev_path(child));
smp_write_intsrc_pci_bridge(mc, irqtype,
irqflag, child, dstapic, dstirq_x);
}
if ((child->class >> 16) != PCI_BASE_CLASS_BRIDGE) {
/* pci device */
printk(BIOS_DEBUG, "route irq: %s\n",
dev_path(child));
for (i = 0; i < 4; i++)
smp_write_intsrc(mc, irqtype, irqflag,
srcbus, (slot<<2)|i, dstapic,
dstirq_x[i]);
goto next;
}

next:
child = child->sibling;
switch (child->class>>8) {
case PCI_CLASS_BRIDGE_PCI:
case PCI_CLASS_BRIDGE_PCMCIA:
case PCI_CLASS_BRIDGE_CARDBUS:
printk(BIOS_DEBUG, "route irq bridge: %s\n",
dev_path(child));
smp_write_intsrc_pci_bridge(mc, irqtype,
irqflag, child, dstapic, dstirq_x);
}

next:
child = child->sibling;
}
}

Expand Down Expand Up @@ -478,17 +476,16 @@ void mptable_write_buses(struct mp_config_table *mc, int *max_pci_bus,
memset(buses, 0, sizeof(buses));

for (dev = all_devices; dev; dev = dev->next) {
struct bus *bus;
for (bus = dev->link_list; bus; bus = bus->next) {
if (bus->secondary > 255) {
printk(BIOS_ERR,
"A bus claims to have a bus ID > 255?!? Aborting");
return;
}
buses[bus->secondary] = 1;
if (highest < bus->secondary)
highest = bus->secondary;
struct bus *bus = dev->link_list;
if (!bus)
continue;
if (bus->secondary > 255) {
printk(BIOS_ERR, "A bus claims to have a bus ID > 255?!? Aborting\n");
return;
}
buses[bus->secondary] = 1;
if (highest < bus->secondary)
highest = bus->secondary;
}
for (i = 0; i <= highest; i++) {
if (buses[i]) {
Expand Down
79 changes: 31 additions & 48 deletions src/device/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,13 +187,11 @@ static void read_resources(struct bus *bus)
{
struct device *curdev;

printk(BIOS_SPEW, "%s %s segment group %d bus %d link: %d\n", dev_path(bus->dev),
__func__, bus->segment_group, bus->secondary, bus->link_num);
printk(BIOS_SPEW, "%s %s segment group %d bus %d\n", dev_path(bus->dev),
__func__, bus->segment_group, bus->secondary);

/* Walk through all devices and find which resources they need. */
for (curdev = bus->children; curdev; curdev = curdev->sibling) {
struct bus *link;

if (!curdev->enabled)
continue;

Expand All @@ -207,12 +205,12 @@ static void read_resources(struct bus *bus)
curdev->ops->read_resources(curdev);

/* Read in the resources behind the current device's links. */
for (link = curdev->link_list; link; link = link->next)
read_resources(link);
if (curdev->link_list)
read_resources(curdev->link_list);
}
post_log_clear();
printk(BIOS_SPEW, "%s %s segment group %d bus %d link: %d done\n",
dev_path(bus->dev), __func__, bus->segment_group, bus->secondary, bus->link_num);
printk(BIOS_SPEW, "%s %s segment group %d bus %d done\n",
dev_path(bus->dev), __func__, bus->segment_group, bus->secondary);
}

struct device *vga_pri = NULL;
Expand Down Expand Up @@ -301,8 +299,8 @@ void assign_resources(struct bus *bus)
{
struct device *curdev;

printk(BIOS_SPEW, "%s %s, segment group %d bus %d link: %d\n",
dev_path(bus->dev), __func__, bus->segment_group, bus->secondary, bus->link_num);
printk(BIOS_SPEW, "%s %s, segment group %d bus %d\n",
dev_path(bus->dev), __func__, bus->segment_group, bus->secondary);

for (curdev = bus->children; curdev; curdev = curdev->sibling) {
if (!curdev->enabled || !curdev->resource_list)
Expand All @@ -317,8 +315,8 @@ void assign_resources(struct bus *bus)
curdev->ops->set_resources(curdev);
}
post_log_clear();
printk(BIOS_SPEW, "%s %s, segment group %d bus %d link: %d done\n",
dev_path(bus->dev), __func__, bus->segment_group, bus->secondary, bus->link_num);
printk(BIOS_SPEW, "%s %s, segment group %d bus %d done\n",
dev_path(bus->dev), __func__, bus->segment_group, bus->secondary);
}

/**
Expand All @@ -336,7 +334,6 @@ void assign_resources(struct bus *bus)
static void enable_resources(struct bus *link)
{
struct device *dev;
struct bus *c_link;

for (dev = link->children; dev; dev = dev->sibling) {
if (dev->enabled && dev->ops && dev->ops->enable_resources) {
Expand All @@ -346,8 +343,8 @@ static void enable_resources(struct bus *link)
}

for (dev = link->children; dev; dev = dev->sibling) {
for (c_link = dev->link_list; c_link; c_link = c_link->next)
enable_resources(c_link);
if (dev->link_list)
enable_resources(dev->link_list);
}
post_log_clear();
}
Expand Down Expand Up @@ -394,17 +391,15 @@ static void scan_bus(struct device *busdev)

do_scan_bus = 1;
while (do_scan_bus) {
struct bus *link;
struct bus *link = busdev->link_list;
busdev->ops->scan_bus(busdev);
do_scan_bus = 0;
for (link = busdev->link_list; link; link = link->next) {
if (link->reset_needed) {
if (reset_bus(link))
do_scan_bus = 1;
else
busdev->bus->reset_needed = 1;
}
}
if (!link || !link->reset_needed)
continue;
if (reset_bus(link))
do_scan_bus = 1;
else
busdev->bus->reset_needed = 1;
}

scan_time = stopwatch_duration_msecs(&sw);
Expand Down Expand Up @@ -523,13 +518,11 @@ void dev_configure(void)
*/
void dev_enable(void)
{
struct bus *link;

printk(BIOS_INFO, "Enabling resources...\n");

/* Now enable everything. */
for (link = dev_root.link_list; link; link = link->next)
enable_resources(link);
if (dev_root.link_list)
enable_resources(dev_root.link_list);

printk(BIOS_INFO, "done.\n");
}
Expand All @@ -553,8 +546,7 @@ static void init_dev(struct device *dev)
long init_time;

if (dev->path.type == DEVICE_PATH_I2C) {
printk(BIOS_DEBUG, "smbus: %s[%d]->",
dev_path(dev->bus->dev), dev->bus->link_num);
printk(BIOS_DEBUG, "smbus: %s->", dev_path(dev->bus->dev));
}

printk(BIOS_DEBUG, "%s init\n", dev_path(dev));
Expand All @@ -572,18 +564,16 @@ static void init_dev(struct device *dev)
static void init_link(struct bus *link)
{
struct device *dev;
struct bus *c_link;

for (dev = link->children; dev; dev = dev->sibling) {
post_code(POSTCODE_BS_DEV_INIT);
post_log_path(dev);
init_dev(dev);
}

for (dev = link->children; dev; dev = dev->sibling) {
for (c_link = dev->link_list; c_link; c_link = c_link->next)
init_link(c_link);
}
for (dev = link->children; dev; dev = dev->sibling)
if (dev->link_list)
init_link(dev->link_list);
}

/**
Expand All @@ -594,16 +584,14 @@ static void init_link(struct bus *link)
*/
void dev_initialize(void)
{
struct bus *link;

printk(BIOS_INFO, "Initializing devices...\n");

/* First call the mainboard init. */
init_dev(&dev_root);

/* Now initialize everything. */
for (link = dev_root.link_list; link; link = link->next)
init_link(link);
if (dev_root.link_list)
init_link(dev_root.link_list);
post_log_clear();

printk(BIOS_INFO, "Devices initialized\n");
Expand Down Expand Up @@ -633,15 +621,13 @@ static void final_dev(struct device *dev)
static void final_link(struct bus *link)
{
struct device *dev;
struct bus *c_link;

for (dev = link->children; dev; dev = dev->sibling)
final_dev(dev);

for (dev = link->children; dev; dev = dev->sibling) {
for (c_link = dev->link_list; c_link; c_link = c_link->next)
final_link(c_link);
}
for (dev = link->children; dev; dev = dev->sibling)
if (dev->link_list)
final_link(dev->link_list);
}
/**
* Finalize all devices in the global device tree.
Expand All @@ -651,16 +637,13 @@ static void final_link(struct bus *link)
*/
void dev_finalize(void)
{
struct bus *link;

printk(BIOS_INFO, "Finalize devices...\n");

/* First call the mainboard finalize. */
final_dev(&dev_root);

/* Now finalize everything. */
for (link = dev_root.link_list; link; link = link->next)
final_link(link);
final_link(dev_root.link_list);

printk(BIOS_INFO, "Devices finalized\n");
}

0 comments on commit 80c79a5

Please sign in to comment.