aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/gran/bus/simple_bus.h2
-rw-r--r--include/gran/component.h62
-rw-r--r--include/gran/cpu/riscv/simple_riscv64.h2
-rw-r--r--include/gran/grid/node.h19
-rw-r--r--include/gran/packet.h223
-rw-r--r--include/gran/snoop.h23
6 files changed, 227 insertions, 104 deletions
diff --git a/include/gran/bus/simple_bus.h b/include/gran/bus/simple_bus.h
index 62dd7d2..eb1e821 100644
--- a/include/gran/bus/simple_bus.h
+++ b/include/gran/bus/simple_bus.h
@@ -4,7 +4,7 @@
#ifndef GRAN_SIMPLE_BUS_H
#define GRAN_SIMPLE_BUS_H
-#include <stdint.h>
+#include <gran/component.h>
struct component *create_simple_bus();
stat simple_bus_add(struct component *bus, struct component *component,
diff --git a/include/gran/component.h b/include/gran/component.h
index 4ef94ad..289d0a6 100644
--- a/include/gran/component.h
+++ b/include/gran/component.h
@@ -12,36 +12,20 @@
#include <gran/common.h>
#include <gran/packet.h>
-#include <gran/snoop.h>
struct component;
-typedef stat (*read_callback)(struct component *, struct packet *pkt);
-typedef stat (*write_callback)(struct component *, struct packet *pkt);
-typedef stat (*swap_callback)(struct component *, struct packet *pkt);
-
-typedef stat (*snoop_callback)(struct component *, struct snoop *snoop);
-typedef stat (*ctrl_callback)(struct component *, struct packet *pkt);
-
-typedef stat (*irq_callback)(struct component *, int);
+typedef stat (*receive_callback)(struct component *to, struct component *from, struct packet pkt);
typedef stat (*clock_callback)(struct component *);
typedef stat (*stat_callback)(struct component *, FILE *);
typedef stat (*dts_callback)(struct component *, FILE *);
-
typedef void (*destroy_callback)(struct component *);
struct component {
/* optional */
char *name;
- read_callback read;
- write_callback write;
- swap_callback swap;
-
- snoop_callback snoop;
- ctrl_callback ctrl;
-
- irq_callback irq;
+ receive_callback receive;
clock_callback clock;
dts_callback dts;
@@ -50,48 +34,20 @@ struct component {
destroy_callback destroy;
};
-static inline stat write(struct component *component, struct packet *pkt)
+static inline stat send(struct component *from, struct component *to, struct packet pkt)
{
- assert(packet_type(pkt) == PACKET_WRITE);
- if (!component->write) {
+ if (!to->receive) {
/* printf formatted asserts would maybe be preferable? */
error(
- "tried writing %p:%" PRIuPTR " but it doesn't support writing",
- component->name, packet_addr(pkt));
- return ENOSUCH;
- }
-
- packet_set_state(pkt, PACKET_SENT);
- return component->write(component, pkt);
-}
-
-static inline stat read(struct component *component, struct packet *pkt)
-{
- assert(packet_type(pkt) == PACKET_READ);
- if (!component->read) {
- error(
- "tried reading %p:%" PRIuPTR " but it doesn't support reading",
- component->name, packet_addr(pkt));
- return ENOSUCH;
- }
-
- packet_set_state(pkt, PACKET_SENT);
- return component->read(component, pkt);
-}
-
-static inline stat swap(struct component *component, struct packet *pkt)
-{
- assert(packet_type(pkt) == PACKET_SWAP);
- if (!component->swap) {
- error(
- "tried swapping %p:%" PRIuPTR " but it doesn't support swapping",
- component->name, packet_addr(pkt));
+ "%s:%lx tried sending to %s:%lx",
+ from->name, pkt.from,
+ to->name, pkt.to);
return ENOSUCH;
}
- packet_set_state(pkt, PACKET_SENT);
- return component->swap(component, pkt);
+ return to->receive(to, from, pkt);
}
+#define SEND(x, y, z) send((struct component *)(x), (struct component *)(y), z)
static inline void destroy(struct component *component)
{
diff --git a/include/gran/cpu/riscv/simple_riscv64.h b/include/gran/cpu/riscv/simple_riscv64.h
index 8f66013..fe6e686 100644
--- a/include/gran/cpu/riscv/simple_riscv64.h
+++ b/include/gran/cpu/riscv/simple_riscv64.h
@@ -6,7 +6,7 @@
#include <gran/component.h>
-struct component *create_simple_riscv64(uint32_t start_pc,
+struct component *create_simple_riscv64(uint64_t rcv, uint32_t start_pc,
struct component *imem,
struct component *dmem);
diff --git a/include/gran/grid/node.h b/include/gran/grid/node.h
index 637ac91..16116d2 100644
--- a/include/gran/grid/node.h
+++ b/include/gran/grid/node.h
@@ -11,4 +11,23 @@ stat grid_node_connect(struct component *node,
struct component *up, struct component *down,
struct component *lower, struct component *ascend);
+static inline uint64_t grid_addr(uint8_t u, uint8_t v, uint8_t x, uint8_t y, uint32_t off)
+{
+ return off
+ | ((uint64_t)x << 32)
+ | ((uint64_t)y << 40)
+ | ((uint64_t)u << 48)
+ | ((uint64_t)v << 56)
+ ;
+}
+
+static inline void addr_grid(uint64_t addr, uint32_t *off, uint8_t *x, uint8_t *y, uint8_t *u, uint8_t *v)
+{
+ if (off) *off = addr & 0xffffffff;
+ if (x) *x = (addr >> 32) & 0xff;
+ if (y) *y = (addr >> 40) & 0xff;
+ if (u) *u = (addr >> 48) & 0xff;
+ if (v) *v = (addr >> 56) & 0xff;
+}
+
#endif /* GRAN_GRID_NODE_H */
diff --git a/include/gran/packet.h b/include/gran/packet.h
index ab07b56..5f8bd9c 100644
--- a/include/gran/packet.h
+++ b/include/gran/packet.h
@@ -4,44 +4,215 @@
#ifndef GRAN_PACKET_H
#define GRAN_PACKET_H
+#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
+#include <assert.h>
+#include <string.h>
-enum packet_state {
- PACKET_INIT,
- PACKET_FAILED,
- PACKET_SENT,
- PACKET_WAITING,
- PACKET_DONE,
+enum packet_flags {
+ PACKET_READ = (1 << 0),
+ PACKET_WRITE = (1 << 1),
+ PACKET_ATOMIC = (1 << 2),
+ PACKET_ERROR = (1 << 3),
+ PACKET_DONE = (1 << 4)
};
-enum packet_type {
- PACKET_READ,
- PACKET_WRITE,
- PACKET_SWAP,
- PACKET_SNOOP,
- PACKET_CTRL,
+struct packet {
+ uint64_t from;
+ uint64_t to;
+ uint64_t mask;
+ uint8_t data[64];
+ enum packet_flags flags;
};
-struct packet;
+static inline struct packet response(struct packet pkt)
+{
+ uint64_t from = pkt.from;
+ uint64_t to = pkt.to;
+ pkt.from = to;
+ pkt.to = from;
+ return pkt;
+}
-struct packet *create_packet(enum packet_type type, uintptr_t addr,
- size_t size);
+static inline void set_flags(struct packet *pkt, enum packet_flags flags)
+{
+ pkt->flags |= flags;
+}
-struct packet *create_packet_with(enum packet_type type, uintptr_t addr,
- size_t size, void *data);
+static inline void clear_flags(struct packet *pkt, enum packet_flags flags)
+{
+ pkt->flags &= ~flags;
+}
-struct packet *reuse_packet(struct packet *pkt, enum packet_type type,
- uintptr_t addr, size_t size, void *data);
+static inline bool is_set(struct packet *pkt, enum packet_flags flags)
+{
+ return pkt->flags & flags;
+}
-enum packet_type packet_type(struct packet *pkt);
-enum packet_state packet_state(struct packet *pkt);
-void packet_set_state(struct packet *pkt, enum packet_state state);
+static inline uint64_t packet_align(uint64_t addr)
+{
+ return addr & ~(64 - 1);
+}
-size_t packet_size(struct packet *pkt);
-uint64_t packet_addr(struct packet *pkt);
-void *packet_data(struct packet *pkt);
+static inline uint64_t packet_mask(uint64_t addr, uint64_t size)
+{
+ assert(size <= 64);
+ uint64_t mask = size == 64 ? ((uint64_t)-1) : (((uint64_t)1 << size) - 1);
+ uint64_t aligned = packet_align(addr);
+ uint64_t diff = addr - aligned;
-void destroy_packet(struct packet *pkt);
+ assert((diff == 0) || ((mask >> (64 - diff)) == 0));
+ mask <<= diff;
+ return mask;
+}
+
+static inline uint64_t packet_convsize(struct packet *pkt)
+{
+ int start = __builtin_ffsll(pkt->mask);
+ if (start == 0)
+ return 0;
+
+ switch ((pkt->mask >> (start - 1)) & 0xff) {
+ case 0x01: return 1;
+ case 0x03: return 2;
+ case 0x0f: return 4;
+ case 0xff: return 8;
+ default: abort();
+ }
+
+ return 0;
+}
+
+static inline uint64_t packet_convto(struct packet *pkt)
+{
+ int start = __builtin_ffsll(pkt->mask);
+ if (start == 0)
+ return pkt->to;
+
+ return pkt->to + (start - 1);
+}
+
+static inline uint64_t packet_convfrom(struct packet *pkt)
+{
+ int start = __builtin_ffsll(pkt->mask);
+ if (start == 0)
+ return pkt->from;
+
+ return pkt->from + (start - 1);
+}
+
+static inline int64_t packet_convi8(struct packet *pkt)
+{
+ int start = __builtin_ffsll(pkt->mask);
+ assert(start != 0);
+
+ return pkt->data[start - 1];
+}
+
+static inline uint8_t packet_convu8(struct packet *pkt)
+{
+ int start = __builtin_ffsll(pkt->mask);
+ assert(start != 0);
+
+ return pkt->data[start - 1];
+}
+
+static inline int16_t packet_convi16(struct packet *pkt)
+{
+ int start = __builtin_ffsll(pkt->mask);
+ assert(start != 0);
+
+ int16_t res = 0;
+ memcpy(&res, pkt->data + (start - 1), 2);
+ return res;
+}
+
+static inline uint16_t packet_convu16(struct packet *pkt)
+{
+ int start = __builtin_ffsll(pkt->mask);
+ assert(start != 0);
+
+ uint16_t res = 0;
+ memcpy(&res, pkt->data + (start - 1), 2);
+ return res;
+}
+
+static inline int32_t packet_convi32(struct packet *pkt)
+{
+ int start = __builtin_ffsll(pkt->mask);
+ assert(start != 0);
+
+ int32_t res = 0;
+ memcpy(&res, pkt->data + (start - 1), 4);
+ return res;
+}
+
+static inline uint32_t packet_convu32(struct packet *pkt)
+{
+ int start = __builtin_ffsll(pkt->mask);
+ assert(start != 0);
+
+ uint32_t res = 0;
+ memcpy(&res, pkt->data + (start - 1), 4);
+ return res;
+}
+
+static inline int64_t packet_convi64(struct packet *pkt)
+{
+ int start = __builtin_ffsll(pkt->mask);
+ assert(start != 0);
+
+ int64_t res = 0;
+ memcpy(&res, pkt->data + (start - 1), 8);
+ return res;
+}
+
+static inline uint64_t packet_convu64(struct packet *pkt)
+{
+ int start = __builtin_ffsll(pkt->mask);
+ assert(start != 0);
+
+ uint64_t res = 0;
+ memcpy(&res, pkt->data + (start - 1), 8);
+ return res;
+}
+
+static inline struct packet create_packet(uint64_t from, uint64_t to, uint64_t size, void *data, enum packet_flags flags)
+{
+ assert(size <= 64);
+ assert(packet_align(from) == from);
+
+ uint64_t aligned = packet_align(to);
+ uint64_t mask = packet_mask(to, size);
+ struct packet pkt = (struct packet){
+ .from = from,
+ .to = aligned,
+ .mask = mask,
+ .data = {},
+ .flags = flags
+ };
+
+ if (is_set(&pkt, PACKET_WRITE))
+ memcpy(pkt.data + (to - aligned), data, size);
+
+ return pkt;
+}
+
+static inline void checked_copyto(struct packet *pkt, uint8_t *data)
+{
+ for (size_t i = 0; i < 64; ++i) {
+ if (pkt->mask & ((uint64_t)1 << i))
+ pkt->data[i] = data[i];
+ }
+}
+
+static inline void checked_copyfrom(struct packet *pkt, uint8_t *data)
+{
+ for (size_t i = 0; i < 64; ++i) {
+ if (pkt->mask & ((uint64_t)1 << i))
+ data[i] = pkt->data[i];
+ }
+}
#endif /* GRAN_PACKET_H */
diff --git a/include/gran/snoop.h b/include/gran/snoop.h
deleted file mode 100644
index 5254984..0000000
--- a/include/gran/snoop.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* SPDX-License-Identifier: copyleft-next-0.3.1 */
-/* Copyright 2023 Kim Kuparinen < kimi.h.kuparinen@gmail.com > */
-
-#ifndef GRAN_SNOOP_H
-#define GRAN_SNOOP_H
-
-#include <stdint.h>
-
-enum snoop_state {
- SNOOP_UNANSWERED,
- SNOOP_ANSWERED,
-};
-
-struct snoop;
-
-struct snoop *create_snoop(uintptr_t addr, size_t size);
-void destroy_snoop(struct snoop *snoop);
-
-enum snoop_state snoop_state(struct snoop *snoop);
-uintptr_t snoop_addr(struct snoop *snoop);
-size_t snoop_size(struct snoop *snoop);
-
-#endif /* GRAN_SNOOP_H */