diff --git a/config/examples/ppc_config.xml b/config/examples/ppc_config.xml
index 19dc043..d720d7d 100644
--- a/config/examples/ppc_config.xml
+++ b/config/examples/ppc_config.xml
@@ -68,7 +68,7 @@
-
+
diff --git a/drivers/pci.c b/drivers/pci.c
index 4bc02c9..3c3b78f 100644
--- a/drivers/pci.c
+++ b/drivers/pci.c
@@ -93,6 +89,16 @@ static inline int pci_encode_phys_addr(u32 *phys, int flags, int space_code,
return 3;
}
+static inline void pci_decode_phys_addr(u32 *phys, int *flags, int *space_code,
+ pci_addr *dev, uint8_t *reg, uint64_t *addr)
+{
+ *reg = phys[0] & 0xff;
+ *dev = phys[0] & 0xffff00;
+ *space_code = (phys[0] >> 24) & 3;
+ *flags = phys[0] & 0xfc000000;
+ *addr = (uint64_t)phys[1] << 32 | phys[2];
+}
+
static inline int pci_encode_size(u32 *prop, uint64_t size)
{
return encode_int32_cells(2, prop, size);
@@ -141,11 +147,15 @@ static void dump_reg_property(const char* description, int nreg, u32 *reg)
static unsigned long pci_bus_addr_to_host_addr(int space, uint32_t ba)
{
- if (space == IO_SPACE) {
+ PCI_DPRINTF("%s space=%d ba=0x%"PRIx32"\n", __func__, space, ba);
+ switch (space) {
+ case CONFIGURATION_SPACE:
+ return arch->cfg_addr;
+ case IO_SPACE:
return arch->io_base + (unsigned long)ba;
- } else if (space == MEMORY_SPACE_32) {
+ case MEMORY_SPACE_32:
return arch->host_pci_base + (unsigned long)ba;
- } else {
+ default:
/* Return unaltered to aid debugging property values */
return (unsigned long)ba;
}
@@ -363,20 +373,11 @@ ob_pci_encode_unit(int *idx)
ss, dev, fn, buf);
}
-/* 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 mask;
- int flags, space_code;
+/* Map a memory region to a virt address */
+/* This should be simpler but there are some differences to handle */
+static ucell ob_pci_map(phys_addr_t phys, ucell size) {
ucell virt;
-
- pci_decode_pci_addr(ba, &flags, &space_code, &mask);
-
- phys = pci_bus_addr_to_host_addr(space_code,
- ba & ~mask);
-
+ PCI_DPRINTF("%s: phys=0x"FMT_plx" size="FMT_ucell"\n", __func__, phys, size);
#if defined(CONFIG_OFMEM)
ofmem_claim_phys(phys, size, 0);
@@ -403,23 +404,44 @@ static void ob_pci_unmap(ucell virt, ucell size) {
#endif
}
+/* 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_in(uint32_t ba, ucell size) {
+ phys_addr_t phys;
+ uint32_t mask;
+ int flags, space_code;
+
+ pci_decode_pci_addr(ba, &flags, &space_code, &mask);
+ phys = pci_bus_addr_to_host_addr(space_code, ba & ~mask);
+ return ob_pci_map(phys, size);
+}
+
/* ( 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;
+ uint32_t phys[3];
+ ucell size, virt;
+ int flags, space_code;
+ pci_addr dev;
+ uint8_t reg;
+ uint64_t addr;
PCI_DPRINTF("ob_pci_bar_map_in idx=%p\n", idx);
size = POP();
- POP();
- POP();
- ba = POP();
+ phys[0] = POP();
+ phys[1] = POP();
+ phys[2] = POP();
- virt = ob_pci_map(ba, size);
+ pci_decode_phys_addr(phys, &flags, &space_code, &dev, ®, &addr);
+ /* Tell compiler we won't use dev and reg: */
+ (void)dev, (void)reg;
+ addr &= (space_code == IO_SPACE ? ~1ULL : ~0xfULL);
+ addr = pci_bus_addr_to_host_addr(space_code, addr);
+ virt = ob_pci_map(addr, size);
PUSH(virt);
}
@@ -459,7 +481,7 @@ NODE_METHODS(ob_pci_bus_node) = {
{ "close", ob_pci_close },
{ "decode-unit", ob_pci_decode_unit },
{ "encode-unit", ob_pci_encode_unit },
- { "pci-map-in", ob_pci_bus_map_in },
+ { "map-in", ob_pci_bus_map_in },
{ "dma-alloc", ob_pci_dma_alloc },
{ "dma-free", ob_pci_dma_free },
{ "dma-map-in", ob_pci_dma_map_in },
@@ -473,7 +495,7 @@ static void
ob_pci_bridge_map_in(int *idx)
{
/* As per the IEEE-1275 PCI specification, chain up to the parent */
- call_parent_method("pci-map-in");
+ call_parent_method("map-in");
}
NODE_METHODS(ob_pci_bridge_node) = {
@@ -481,7 +503,7 @@ NODE_METHODS(ob_pci_bridge_node) = {
{ "close", ob_pci_close },
{ "decode-unit", ob_pci_decode_unit },
{ "encode-unit", ob_pci_encode_unit },
- { "pci-map-in", ob_pci_bridge_map_in },
+ { "map-in", ob_pci_bridge_map_in },
{ "dma-alloc", ob_pci_dma_alloc },
{ "dma-free", ob_pci_dma_free },
{ "dma-map-in", ob_pci_dma_map_in },
@@ -744,7 +766,7 @@ int sungem_config_cb (const pci_config_t *config)
#define MAC_ADDR2 (0x6088UL/4) /* MAC Address 2 Register */
/* Map PCI memory BAR 0 to access the sungem registers */
- virt = ob_pci_map(config->assigned[0], 0x8000);
+ virt = ob_pci_map_in(config->assigned[0], 0x8000);
mmio = (void *)(uintptr_t)virt;
val = __le32_to_cpu(*(mmio + MAC_ADDR0));
@@ -1220,10 +1242,10 @@ int lsi53c810_config_cb(const pci_config_t *config)
ob_pci_enable_bus_master(config);
/* Map PCI memory BAR 1: LSI MMIO */
- mmio = ob_pci_map(config->assigned[1], 0x400);
+ mmio = ob_pci_map_in(config->assigned[1], 0x400);
/* Map PCI memory BAR 2: LSI RAM */
- ram = ob_pci_map(config->assigned[2], 0x400);
+ ram = ob_pci_map_in(config->assigned[2], 0x400);
ob_lsi_init(config->path, mmio, ram);
#endif
diff --git a/drivers/vga.fs b/drivers/vga.fs
index 53dcff0..f3ffda7 100644
--- a/drivers/vga.fs
+++ b/drivers/vga.fs
@@ -146,14 +146,14 @@ defer vbe-iow!
: map-fb ( -- )
cfg-bar0 pci-bar>pci-addr if \ ( pci-addr.lo pci-addr.mid pci-addr.hi size )
- " pci-map-in" $call-parent
+ " map-in" $call-parent
to fb-addr
then
;
: map-mmio ( -- )
cfg-bar2 pci-bar>pci-addr if \ ( pci-addr.lo pci-addr.mid pci-addr.hi size )
- " pci-map-in" $call-parent
+ " map-in" $call-parent
to mmio-addr
then
;
diff --git a/forth/device/other.fs b/forth/device/other.fs
index 1bed9b8..0ff34b6 100644
--- a/forth/device/other.fs
+++ b/forth/device/other.fs
@@ -58,21 +58,27 @@ defer (poke)
\ 5.3.7.2 Device-register access
: rb@ ( addr -- byte )
+ ioc@
;
: rw@ ( waddr -- w )
+ iow@
;
: rl@ ( qaddr -- quad )
+ iol@
;
: rb! ( byte addr -- )
+ ioc!
;
: rw! ( w waddr -- )
+ iow!
;
: rl! ( quad qaddr -- )
+ iol!
;
: rx@ ( oaddr - o )