From 0464b7765aa4d1fc2178e443a3b37d19cfe541a0 Mon Sep 17 00:00:00 2001 From: Kimplul Date: Sun, 2 Mar 2025 21:45:51 +0200 Subject: add ideal allocation tracker + Kind of like CHERI, but uses out-of-line pointer information. The idea is that a core that is compatible with ALLOC_IF queries the allocation tracker if an address is legal and gets a response. This ideal tracker effectively has infinite memory and doesn't talk to any other components, but a real implementation might want to limit the allocations per process or chat with some reserved memory region somewhere else in the system to maintain a binary tree or something. --- tests/simple_ideal_alloc/testbench.c | 119 +++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 tests/simple_ideal_alloc/testbench.c (limited to 'tests/simple_ideal_alloc/testbench.c') diff --git a/tests/simple_ideal_alloc/testbench.c b/tests/simple_ideal_alloc/testbench.c new file mode 100644 index 0000000..703c2a8 --- /dev/null +++ b/tests/simple_ideal_alloc/testbench.c @@ -0,0 +1,119 @@ +#include +#include "testbench.h" + +struct reg { + struct packet pkt; + bool busy; +}; + +struct tb { + struct component component; + struct component *dut; + struct reg in; + + enum { + ADD_REGION, + QUERY_EXISTING, + REMOVE_REGION, + QUERY_NONEXISTING, + FINAL + } state; +}; + +static stat tb_receive(struct tb *tb, struct component *from, struct packet pkt) +{ + assert(tb->dut == from); + tb->in.pkt = pkt; + tb->in.busy = true; + return OK; +} + +static stat tb_clock(struct tb *tb) +{ + assert(tb->dut); + + switch (tb->state) { + case ADD_REGION: { + struct alloc_if_new n = {.space = 0, .start = 0, .end = 10}; + struct packet pkt = create_packet(0, ALLOC_IF_NEW, sizeof(n), &n, PACKET_WRITE); + assert(SEND(tb, tb->dut, pkt) == OK); + tb->state = QUERY_EXISTING; + break; + } + + case QUERY_EXISTING: { + if (!tb->in.busy) + break; + + struct alloc_if_r *r = (struct alloc_if_r *)&tb->in.pkt.data; + assert(r->r == ALLOC_IF_OK); + + struct alloc_if_q q = {.space = 0, .addr = 5}; + struct packet pkt = create_packet(0, ALLOC_IF_Q, sizeof(q), &q, PACKET_WRITE); + assert(SEND(tb, tb->dut, pkt) == OK); + tb->state = REMOVE_REGION; + tb->in.busy = false; + break; + } + + case REMOVE_REGION: { + if (!tb->in.busy) + break; + + struct alloc_if_r *r = (struct alloc_if_r *)&tb->in.pkt.data; + assert(r->r == ALLOC_IF_OK); + assert(r->start == 0); + assert(r->end == 10); + + struct alloc_if_rm rm = {.space = 0, .start = 0, .end = 10}; + struct packet pkt = create_packet(0, ALLOC_IF_RM, sizeof(rm), &rm, PACKET_WRITE); + assert(SEND(tb, tb->dut, pkt) == OK); + tb->state = QUERY_NONEXISTING; + tb->in.busy = false; + break; + } + + case QUERY_NONEXISTING: { + if (!tb->in.busy) + break; + + struct alloc_if_r *r = (struct alloc_if_r *)&tb->in.pkt.data; + assert(r->r == ALLOC_IF_OK); + + struct alloc_if_q q = {.space = 0, .addr = 5}; + struct packet pkt = create_packet(0, ALLOC_IF_Q, sizeof(q), &q, PACKET_WRITE); + assert(SEND(tb, tb->dut, pkt) == OK); + tb->state = FINAL; + tb->in.busy = false; + break; + } + + case FINAL: { + if (!tb->in.busy) + break; + + struct alloc_if_r *r = (struct alloc_if_r *)&tb->in.pkt.data; + assert(r->r != ALLOC_IF_OK); + return DONE; + } + + default: abort(); + } + + return OK; +} + +struct component *create_testbench() +{ + struct tb *tb = calloc(1, sizeof(struct tb)); + tb->component.clock = (clock_callback)tb_clock; + tb->component.receive = (receive_callback)tb_receive; + return (struct component *)tb; +} + +stat testbench_connect(struct component *tb, struct component *dut) +{ + struct tb *t = (struct tb *)tb; + t->dut = dut; + return OK; +} -- cgit v1.3