Currently all PCI devices except display devices are initialised with
simple open and close words that are effectively a no-op, but enable
the device to be accessed.
Unfortunately this means that if devices have custom open and close words
then the existing ones are overwritten causing OpenBIOS to emit warnings
such as "open isn't unique" on the console.
Resolve this by defaulting all PCI devices to the empty PCI node template
ob_pci_empty_node and then adding the simple open and close words after
the device has been initialised if they do not already exist.
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland(a)ilande.co.uk>
---
drivers/pci.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/pci.c b/drivers/pci.c
index d698364..c7b2bd2 100644
--- a/drivers/pci.c
+++ b/drivers/pci.c
@@ -49,7 +49,7 @@
/* DECLARE data structures for the nodes. */
DECLARE_UNNAMED_NODE( ob_pci_bus_node, INSTALL_OPEN, 2*sizeof(int) );
-DECLARE_UNNAMED_NODE( ob_pci_simple_node, INSTALL_OPEN, 2*sizeof(int) );
+DECLARE_UNNAMED_NODE( ob_pci_simple_node, 0, 2*sizeof(int) );
DECLARE_UNNAMED_NODE( ob_pci_empty_node, 0, 2*sizeof(int) );
const pci_arch_t *arch;
@@ -399,7 +399,6 @@ NODE_METHODS(ob_pci_bus_node) = {
};
NODE_METHODS(ob_pci_simple_node) = {
- { NULL, ob_pci_initialize },
{ "open", ob_pci_open },
{ "close", ob_pci_close },
};
@@ -1418,11 +1417,8 @@ static void ob_configure_pci_device(const char* parent_path,
REGISTER_NAMED_NODE_PHANDLE(ob_pci_bus_node, config.path, phandle);
}
break;
- case PCI_CLASS_DISPLAY:
- REGISTER_NAMED_NODE_PHANDLE(ob_pci_empty_node, config.path, phandle);
- break;
default:
- REGISTER_NAMED_NODE_PHANDLE(ob_pci_simple_node, config.path, phandle);
+ REGISTER_NAMED_NODE_PHANDLE(ob_pci_empty_node, config.path, phandle);
break;
}
@@ -1460,6 +1456,11 @@ static void ob_configure_pci_device(const char* parent_path,
pci_dev->config_cb(&config);
}
+ /* 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);
+ }
+
/* device is configured so we may move it out of scope */
device_end();
--
1.7.10.4
This patchset is part of the ongoing work to add virtio support to
OpenBIOS, yet self-contained enough to be spun out as a separate
patchset.
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland(a)ilande.co.uk>
v2:
- Add comment explaining BE access for file API
- Add mising byte swap macros to fw_cfg_find_file()
Mark Cave-Ayland (3):
fw_cfg: split fw_cfg_read() into fw_cfg_read() and
fw_cfg_read_bytes()
fw_cfg: add fw_cfg_find_file() and fw_cfg_read_file() functions
fw_cfg: implement fw-cfg-read-file Forth word
drivers/fw_cfg.c | 89 +++++++++++++++++++++++++++++++++++++++---
include/arch/common/fw_cfg.h | 16 ++++++++
libopenbios/init.c | 7 +++-
3 files changed, 105 insertions(+), 7 deletions(-)
--
1.7.10.4
This patchset is part of the ongoing work to add virtio support to
OpenBIOS, yet self-contained enough to be spun out as a separate
patchset.
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland(a)ilande.co.uk>
Mark Cave-Ayland (3):
fw_cfg: split fw_cfg_read() into fw_cfg_read() and
fw_cfg_read_bytes()
fw_cfg: add fw_cfg_find_file() and fw_cfg_read_file() functions
fw_cfg: implement fw-cfg-read-file Forth word
drivers/fw_cfg.c | 88 +++++++++++++++++++++++++++++++++++++++---
include/arch/common/fw_cfg.h | 16 ++++++++
libopenbios/init.c | 7 +++-
3 files changed, 104 insertions(+), 7 deletions(-)
--
1.7.10.4
The current PCI implementation is designed for a 32-bit PCI bus. When
a 64-bit BAR is encountered during PCI bus enumeration, currently we
treat the MSB BAR the same as a standard 32-bit BAR, attempting to guess
its size by setting to 0xffffffff and reading back the response which
returns back an invalid size of 0 and fails.
This has the effect of setting the MSB BAR to 0xffffffff meaning that
64-bit BARs are mapped at the top of PCI memory in the wrong location.
Handle this case by ignoring the MSB BAR when we detect a 64-bit BAR
leaving it at its default value of zero. This solves the issue by
ensuring that all 64-bit BARs are mapped within 32-bit PCI space which
is fine for the PPC/SPARC64 machines we care about.
Most noticeably this solves the issue of virtio modern devices (which
use 64-bit BARs under QEMU) causing a kernel panic upon startup on
qemu-system-sparc64 because they are mapped at the wrong address by OpenBIOS.
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland(a)ilande.co.uk>
---
drivers/pci.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/pci.c b/drivers/pci.c
index c998280..2e09d0a 100644
--- a/drivers/pci.c
+++ b/drivers/pci.c
@@ -1202,9 +1202,9 @@ ob_pci_configure(pci_addr addr, pci_config_t *config, int num_regs, int rom_bar,
unsigned long *mem_base, unsigned long *io_base)
{
- uint32_t omask;
+ uint32_t omask, mask;
uint16_t cmd;
- int reg;
+ int reg, flags, space_code;
pci_addr config_addr;
ob_pci_configure_irq(addr, config);
@@ -1216,6 +1216,14 @@ ob_pci_configure(pci_addr addr, pci_config_t *config, int num_regs, int rom_bar,
ob_pci_configure_bar(addr, config, reg, config_addr,
&omask, mem_base,
io_base);
+
+ /* Ignore 64-bit BAR MSBs (always map in 32-bit space) */
+ pci_decode_pci_addr(config->assigned[reg],
+ &flags, &space_code, &mask);
+
+ if (space_code == MEMORY_SPACE_64) {
+ reg++;
+ }
}
if (rom_bar) {
--
1.7.10.4