This is so that it can be called directly from C rather than just the pci-map-in Forth binding.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- drivers/pci.c | 53 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 20 deletions(-)
diff --git a/drivers/pci.c b/drivers/pci.c index 88f11c6..e16ce3c 100644 --- a/drivers/pci.c +++ b/drivers/pci.c @@ -367,28 +367,20 @@ ob_pci_encode_unit(int *idx) ss, dev, fn, buf); }
-/* ( pci-addr.lo pci-addr.mid pci-addr.hi size -- virt ) */ - -static void -ob_pci_bus_map_in(int *idx) -{ +/* Map PCI MMIO or IO space from the BAR address. Note it is up to the caller + to understand whether the resulting address is in MEM or IO space and + use the appropriate accesses */ +static ucell ob_pci_map(uint32_t ba, ucell size) { phys_addr_t phys; - uint32_t ba; - ucell size, virt, tmp; - int space; - - PCI_DPRINTF("ob_pci_bar_map_in idx=%p\n", idx); - - size = POP(); - tmp = POP(); - POP(); - ba = POP(); - - /* Get the space from the pci-addr.hi */ - space = ((tmp & PCI_RANGE_TYPE_MASK) >> 24); - - phys = pci_bus_addr_to_host_addr(space, ba); + uint32_t mask; + int flags, space_code; + ucell virt; + + pci_decode_pci_addr(ba, &flags, &space_code, &mask);
+ phys = pci_bus_addr_to_host_addr(space_code, + ba & ~mask); + #if defined(CONFIG_OFMEM) ofmem_claim_phys(phys, size, 0);
@@ -406,6 +398,27 @@ ob_pci_bus_map_in(int *idx) virt = phys; #endif
+ return virt; +} + +/* ( pci-addr.lo pci-addr.mid pci-addr.hi size -- virt ) */ + +static void +ob_pci_bus_map_in(int *idx) +{ + uint32_t ba; + ucell size; + ucell virt; + + PCI_DPRINTF("ob_pci_bar_map_in idx=%p\n", idx); + + size = POP(); + POP(); + POP(); + ba = POP(); + + virt = ob_pci_map(ba, size); + PUSH(virt); }