summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Cave-Ayland <mark.cave-ayland@ilande.co.uk>2019-08-18 21:16:50 +0100
committerMark Cave-Ayland <mark.cave-ayland@ilande.co.uk>2019-08-18 21:16:50 +0100
commitd5c86af027ebfb296ead6b43fa7256c5e85321b2 (patch)
treea6008faadd267b6166baab86019d6d7099666418
parentadd8a184fbb2c8cf543f54f8927fb445f288ec18 (diff)
downloadqemu-openbios-d5c86af027ebfb296ead6b43fa7256c5e85321b2.tar.gz
pci: convert to use BIND_NODE_METHODS() macro
Moving the setup of PCI devices to within a new-device...finish-device sequence as part of the conversion further enables us to move the PCI host bridge configuration logic from ob_pci_init() to ob_configure_pci_device() where it belongs. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
-rw-r--r--drivers/pci.c96
1 files changed, 43 insertions, 53 deletions
diff --git a/drivers/pci.c b/drivers/pci.c
index 60e39487..623f649f 100644
--- a/drivers/pci.c
+++ b/drivers/pci.c
@@ -528,7 +528,9 @@ static void pci_set_bus_range(const pci_config_t *config)
set_property(dev, "bus-range", (char *)props, 2 * sizeof(props[0]));
}
-static void pci_host_set_reg(phandle_t phandle)
+static void ob_pci_reload_device_path(phandle_t phandle, pci_config_t *config);
+
+static void pci_host_set_reg(phandle_t phandle, pci_config_t *config)
{
phandle_t dev = phandle;
@@ -544,6 +546,8 @@ static void pci_host_set_reg(phandle_t phandle)
set_property(dev, "reg", (char *)props, ncells * sizeof(props[0]));
+ ob_pci_reload_device_path(dev, config);
+
#if defined(CONFIG_DEBUG_PCI)
dump_reg_property("pci_host_set_reg", 4, props);
#endif
@@ -579,8 +583,6 @@ static void pci_host_set_ranges(const pci_config_t *config)
int host_config_cb(const pci_config_t *config)
{
- //XXX this overrides "reg" property
- pci_host_set_reg(get_cur_dev());
pci_host_set_ranges(config);
return 0;
@@ -1265,6 +1267,7 @@ static void ob_pci_add_properties(phandle_t phandle,
uint8_t rev;
uint8_t class_prog;
uint32_t class_code;
+ char path[256];
vendor_id = pci_config_read16(addr, PCI_VENDOR_ID);
device_id = pci_config_read16(addr, PCI_DEVICE_ID);
@@ -1272,24 +1275,22 @@ static void ob_pci_add_properties(phandle_t phandle,
class_prog = pci_config_read8(addr, PCI_CLASS_PROG);
class_code = pci_config_read16(addr, PCI_CLASS_DEVICE);
+ /* Default path if we don't match anything */
+ snprintf(path, sizeof(path), "pci%x,%x", vendor_id, device_id);
+
if (pci_dev) {
/**/
if (pci_dev->name) {
push_str(pci_dev->name);
- fword("encode-string");
- push_str("name");
- fword("property");
+ fword("device-name");
} else {
- char path[256];
- snprintf(path, sizeof(path),
- "pci%x,%x", vendor_id, device_id);
push_str(path);
- fword("encode-string");
- push_str("name");
- fword("property");
+ fword("device-name");
}
} else {
PCI_DPRINTF("*** missing pci_dev\n");
+ push_str(path);
+ fword("device-name");
}
/* create properties as described in 2.5 */
@@ -1335,15 +1336,11 @@ static void ob_pci_add_properties(phandle_t phandle,
if (pci_dev) {
if (pci_dev->type) {
push_str(pci_dev->type);
- fword("encode-string");
- push_str("device_type");
- fword("property");
+ fword("device-type");
}
if (pci_dev->model) {
push_str(pci_dev->model);
- fword("encode-string");
- push_str("model");
- fword("property");
+ fword("model");
}
if (pci_dev->compat)
set_property(dev, "compatible",
@@ -1765,7 +1762,7 @@ static phandle_t ob_configure_pci_device(const char* parent_path,
uint8_t class, subclass, iface;
int num_bars, rom_bar;
- phandle_t phandle = 0;
+ phandle_t phandle = 0, t;
int is_host_bridge = 0;
if (!ob_pci_read_identification(bus, devnum, fn, &vid, &did, &class, &subclass)) {
@@ -1789,54 +1786,52 @@ static phandle_t ob_configure_pci_device(const char* parent_path,
}
}
- /* stop adding host bridge accessible from it's primary bus
- PCI host bridge is to be added by host code
- */
if (class == PCI_BASE_CLASS_BRIDGE &&
subclass == PCI_SUBCLASS_BRIDGE_HOST) {
is_host_bridge = 1;
}
+ /* stop adding host bridge accessible from it's primary bus
+ PCI host bridge is to be added by host code
+ */
if (is_host_bridge) {
/* reuse device tree node */
PCI_DPRINTF("host bridge found - ");
- snprintf(config.path, sizeof(config.path),
- "%s", parent_path);
+
+ t = find_dev(parent_path);
+ if (get_property(t, "vendor-id", NULL)) {
+ PCI_DPRINTF("host bridge already configured\n");
+ return 0;
+ }
} else if (pci_dev == NULL || pci_dev->name == NULL) {
snprintf(config.path, sizeof(config.path),
"%s/pci%x,%x", parent_path, vid, did);
- }
- else {
+ } else {
snprintf(config.path, sizeof(config.path),
"%s/%s", parent_path, pci_dev->name);
}
+ fword("new-device");
+
PCI_DPRINTF("%s - ", config.path);
config.dev = addr & 0x00FFFFFF;
+ phandle = get_cur_dev();
+
switch (class) {
case PCI_BASE_CLASS_BRIDGE:
if (subclass != PCI_SUBCLASS_BRIDGE_HOST) {
- REGISTER_NAMED_NODE_PHANDLE(ob_pci_bridge_node, config.path, phandle);
+ BIND_NODE_METHODS(phandle, ob_pci_bridge_node);
+ } else {
+ BIND_NODE_METHODS(phandle, ob_pci_bus_node);
}
break;
default:
- REGISTER_NAMED_NODE_PHANDLE(ob_pci_empty_node, config.path, phandle);
+ BIND_NODE_METHODS(phandle, ob_pci_empty_node);
break;
}
- if (is_host_bridge) {
- phandle = find_dev(config.path);
-
- if (get_property(phandle, "vendor-id", NULL)) {
- PCI_DPRINTF("host bridge already configured\n");
- return 0;
- }
- }
-
- activate_dev(phandle);
-
if (htype & PCI_HEADER_TYPE_BRIDGE) {
num_bars = 2;
rom_bar = PCI_ROM_ADDRESS1;
@@ -1852,6 +1847,8 @@ static phandle_t ob_configure_pci_device(const char* parent_path,
if (!is_host_bridge) {
pci_set_reg(phandle, &config, num_bars);
+ } else {
+ pci_host_set_reg(phandle, &config);
}
/* call device-specific configuration callback */
@@ -1862,12 +1859,9 @@ static phandle_t ob_configure_pci_device(const char* parent_path,
/* if devices haven't supplied open/close words then supply them with simple defaults */
if (!find_package_method("open", phandle) && !find_package_method("close", phandle)) {
- REGISTER_NODE_METHODS(ob_pci_simple_node, config.path);
+ BIND_NODE_METHODS(phandle, ob_pci_simple_node);
}
- /* device is configured so we may move it out of scope */
- device_end();
-
/* scan bus behind bridge device */
//if (htype & PCI_HEADER_TYPE_BRIDGE && class == PCI_BASE_CLASS_BRIDGE) {
if ( class == PCI_BASE_CLASS_BRIDGE &&
@@ -1882,6 +1876,8 @@ static phandle_t ob_configure_pci_device(const char* parent_path,
ob_configure_pci_bridge(addr, bus_num, mem_base, io_base, bus, &config);
}
+ fword("finish-device");
+
return phandle;
}
@@ -2103,7 +2099,8 @@ int ob_pci_init(void)
PCI_DPRINTF("Initializing PCI host bridge...\n");
- activate_device("/");
+ push_str("/");
+ fword("find-device");
/* Find all PCI bridges */
@@ -2130,16 +2127,9 @@ int ob_pci_init(void)
/* create root node for host PCI bridge */
/* configure */
- snprintf(config.path, sizeof(config.path), "/pci");
-
- REGISTER_NAMED_NODE_PHANDLE(ob_pci_bus_node, config.path, phandle_host);
-
- pci_host_set_reg(phandle_host);
-
- /* update device path after changing "reg" property */
- ob_pci_reload_device_path(phandle_host, &config);
+ strncpy(config.path, "", sizeof(config.path));
- ob_configure_pci_device(config.path, &bus, &mem_base, &io_base,
+ phandle_host = ob_configure_pci_device(config.path, &bus, &mem_base, &io_base,
bus, devnum, fn, 0);
/* we expect single host PCI bridge