aboutsummaryrefslogtreecommitdiff
path: root/src/components/bus
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/bus')
-rw-r--r--src/components/bus/simple_bus.c64
1 files changed, 49 insertions, 15 deletions
diff --git a/src/components/bus/simple_bus.c b/src/components/bus/simple_bus.c
index 3629ecd..440ff8a 100644
--- a/src/components/bus/simple_bus.c
+++ b/src/components/bus/simple_bus.c
@@ -64,65 +64,94 @@ static stat add_mem_region(struct simple_bus *bus, struct mem_region *new)
return OK;
}
-static stat simple_bus_write(struct simple_bus *bus, uintptr_t addr,
- size_t size, char *buf)
+static stat simple_bus_write(struct simple_bus *bus, struct packet *pkt)
{
/* only one device can drive the bus at one time */
if (mtx_trylock(&bus->lock) != thrd_success)
return EBUSY;
- struct mem_region *mem_region = find_mem_region(bus, addr);
+ struct mem_region *mem_region = find_mem_region(bus, packet_addr(pkt));
if (!mem_region) {
warn("nothing to write on bus %s at %" PRIuPTR,
- bus->component.name, addr);
+ bus->component.name, packet_addr(pkt));
return EBUS;
}
- stat ret = write(mem_region->component, addr, size, buf);
+ stat ret = write(mem_region->component, pkt);
mtx_unlock(&bus->lock);
return ret;
}
-static stat simple_bus_read(struct simple_bus *bus, uintptr_t addr, size_t size,
- char *buf)
+static stat simple_bus_read(struct simple_bus *bus, struct packet *pkt)
{
/* only one device can drive the bus at one time */
if (mtx_trylock(&bus->lock) != thrd_success)
return EBUSY;
- struct mem_region *mem_region = find_mem_region(bus, addr);
+ struct mem_region *mem_region = find_mem_region(bus, packet_addr(pkt));
if (!mem_region) {
warn("nothing to read on bus %s at %" PRIuPTR,
- bus->component.name, addr);
+ bus->component.name, packet_addr(pkt));
return EBUS;
}
- stat ret = read(mem_region->component, addr, size, buf);
+ stat ret = read(mem_region->component, pkt);
mtx_unlock(&bus->lock);
return ret;
}
-static stat simple_bus_swap(struct simple_bus *bus, uintptr_t addr,
- size_t wsize, char *wbuf, size_t rsize, char *rbuf)
+static stat simple_bus_swap(struct simple_bus *bus, struct packet *pkt)
{
if (mtx_trylock(&bus->lock) != thrd_success)
return EBUSY;
- struct mem_region *mem_region = find_mem_region(bus, addr);
+ struct mem_region *mem_region = find_mem_region(bus, packet_addr(pkt));
if (!mem_region) {
warn("nothing to swap on bus %s at %" PRIuPTR,
- bus->component.name, addr);
+ bus->component.name, packet_addr(pkt));
return EBUS;
}
- stat ret = swap(mem_region->component, addr, wsize, wbuf, rsize, rbuf);
+ stat ret = swap(mem_region->component, pkt);
mtx_unlock(&bus->lock);
return ret;
}
+static stat simple_bus_snoop(struct simple_bus *bus, struct snoop *snoop)
+{
+ struct mem_region *cur = bus->mem_regions;
+ while (cur) {
+ if (cur->component->snoop) {
+ stat ret = cur->component->snoop(cur->component, snoop);
+ if (ret)
+ return ret;
+
+ if (snoop_state(snoop) == SNOOP_ANSWERED)
+ return OK;
+ }
+
+ cur = cur->next;
+ }
+
+ return OK;
+}
+
+static void simple_bus_destroy(struct simple_bus *bus)
+{
+ struct mem_region *cur = bus->mem_regions, *next = NULL;
+ if (cur)
+ do {
+ next = cur->next;
+ destroy(cur->component);
+ free(cur);
+ } while ((cur = next));
+
+ free(bus);
+}
+
struct component *create_simple_bus()
{
struct simple_bus *bus = calloc(1, sizeof(struct simple_bus));
@@ -132,6 +161,11 @@ struct component *create_simple_bus()
bus->component.write = (write_callback)simple_bus_write;
bus->component.read = (read_callback)simple_bus_read;
bus->component.swap = (swap_callback)simple_bus_swap;
+ bus->component.snoop = (snoop_callback)simple_bus_snoop;
+ // actually, still not sure about what API I want to use for controls
+ // bus->component.ctrl = (ctrl_callback)simple_bus_ctrl;
+
+ bus->component.destroy = (destroy_callback)simple_bus_destroy;
mtx_init(&bus->lock, mtx_plain);
return (struct component *)bus;