On Sat, 28 Jan 2023, Mark Cave-Ayland wrote:
On 26/01/2023 23:43, BALATON Zoltan wrote:
On Thu, 26 Jan 2023, Mark Cave-Ayland wrote:
On 17/01/2023 18:15, BALATON Zoltan wrote:
On Sun, 25 Sep 2022, BALATON Zoltan wrote:
drivers/pci.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+)
Ping? This was just ignored without any comment so far.
Regards, BALATON Zoltan
diff --git a/drivers/pci.c b/drivers/pci.c index 3567cc3..6ec3b33 100644 --- a/drivers/pci.c +++ b/drivers/pci.c @@ -424,6 +424,60 @@ ob_pci_bus_map_in(int *idx) PUSH(virt); }
+static void +ob_pci_config_read8(int *idx) +{ + cell hi = POP(); + pci_addr addr = PCI_ADDR(PCI_BUS(hi), PCI_DEV(hi), PCI_FN(hi)); + uint8_t val = pci_config_read8(addr, hi & 0xff); + PUSH(val); +}
+static void +ob_pci_config_write8(int *idx) +{ + cell hi = POP(); + pci_addr addr = PCI_ADDR(PCI_BUS(hi), PCI_DEV(hi), PCI_FN(hi)); + cell val = POP(); + pci_config_write8(addr, hi & 0xff, val); +}
+static void +ob_pci_config_read16(int *idx) +{ + cell hi = POP(); + pci_addr addr = PCI_ADDR(PCI_BUS(hi), PCI_DEV(hi), PCI_FN(hi)); + uint16_t val = pci_config_read16(addr, hi & 0xff); + PUSH(val); +}
+static void +ob_pci_config_write16(int *idx) +{ + cell hi = POP(); + pci_addr addr = PCI_ADDR(PCI_BUS(hi), PCI_DEV(hi), PCI_FN(hi)); + cell val = POP(); + pci_config_write16(addr, hi & 0xff, val); +}
+static void +ob_pci_config_read32(int *idx) +{ + cell hi = POP(); + pci_addr addr = PCI_ADDR(PCI_BUS(hi), PCI_DEV(hi), PCI_FN(hi)); + uint32_t val = pci_config_read32(addr, hi & 0xff); + PUSH(val); +}
+static void +ob_pci_config_write32(int *idx) +{ + cell hi = POP(); + pci_addr addr = PCI_ADDR(PCI_BUS(hi), PCI_DEV(hi), PCI_FN(hi)); + cell val = POP(); + pci_config_write32(addr, hi & 0xff, val); +}
static void ob_pci_dma_alloc(int *idx) { @@ -460,6 +514,12 @@ NODE_METHODS(ob_pci_bus_node) = { { "decode-unit", ob_pci_decode_unit }, { "encode-unit", ob_pci_encode_unit }, { "pci-map-in", ob_pci_bus_map_in }, + { "config-b@", ob_pci_config_read8 }, + { "config-b!", ob_pci_config_write8 }, + { "config-w@", ob_pci_config_read16 }, + { "config-w!", ob_pci_config_write16 }, + { "config-l@", ob_pci_config_read32 }, + { "config-l!", ob_pci_config_write32 }, { "dma-alloc", ob_pci_dma_alloc }, { "dma-free", ob_pci_dma_free }, { "dma-map-in", ob_pci_dma_map_in },
I gave this patch a test, and whilst it basically works it seems to be missing some logic around PCI bridges. For example to read the PCI vendor ID on PPC:
0 > cd /pci@80000000/mac-io@10 ok 0 > " /pci@80000000/mac-io@10" open-dev to my-self ok 0 > my-space " config-w@" $call-parent ok 1 > u. 106b ok
and on SPARC64:
0 > cd /pci@1fe,0/pci@1,1/QEMU,VGA@2 ok 0 > " /pci@1fe,0/pci@1,1/QEMU,VGA@2" open-dev to my-self ok 0 > my-space " config-w@" $call-parent undefined method.
I think this needs fixing since assuming the QEMU New World Mac machine moves towards a G4 AGP machine, re-introducing the DEC PCI bridge present in real Macs would cause this to break again.
I've handled that for the map-in and map-out words in this patch:
https://mail.coreboot.org/hyperkitty/list/openbios@openbios.org/message/DRXS...
so similar should work for config-* as well but I wonder if there's a more generic way for a bridge to just try to forward every word it does not know about to it's parent so we don't add these one by one. Any ideas?
From my experience that's quite a common pattern to invoke $call-parent up to the next bus node (I see plenty of examples in Sun's OpenFirmware) so I think it's the right way to do things in a Forth-based firmware environment.
I could not find an easier way so I've sent a v4 adding more of these one line functions for now. But I think eventually these should be cleaned up and replaced with one common function to make this file less cluttered. There's an is-call-parent word in Forth to define such methods but it depends on passing the method name as a string so it's just a shortcut for avoiding writing the method name twice (which some places do even in the same file using is-call-parent). To do that in C the method function should either get the name as an argument or be able to find its own name but I could not figure out how that could be done. So let's go with the ugly version that works and we may clean that up later.
Regards, BALATON Zoltan