Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
isubasinghe committed Feb 28, 2024
1 parent 36bb9a1 commit b8d94d9
Show file tree
Hide file tree
Showing 13 changed files with 2,357 additions and 11 deletions.
504 changes: 504 additions & 0 deletions copy_spec.py

Large diffs are not rendered by default.

103 changes: 103 additions & 0 deletions examples/copy.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
#include <stdbool.h>
#include <string.h>

#include "shared_ringbuffer.h"
#include "util.h"

/* Notification and PPC channels - ensure these align with .system file! */
#define MUX_RX_CH 0
#define CLIENT_CH 1

/* Ring handles */
ring_handle_t rx_ring_mux;
ring_handle_t rx_ring_cli;

/* Ring buffer regions */
uintptr_t rx_free_mux;
uintptr_t rx_used_mux;
uintptr_t rx_free_cli;
uintptr_t rx_used_cli;

/* Buffer data regions */
uintptr_t mux_buffer_data_region;
uintptr_t cli_buffer_data_region;

uintptr_t uart_base;

void rx_return(void)
{
bool enqueued = false;
bool reprocess = true;

while (reprocess) {
while (!ring_empty(rx_ring_mux.used_ring) && !ring_empty(rx_ring_cli.free_ring) &&
!ring_full(rx_ring_mux.free_ring) && !ring_full(rx_ring_cli.used_ring)) {
buff_desc_t cli_buffer, mux_buffer;
int err __attribute__((unused)) = dequeue_free(&rx_ring_cli, &cli_buffer);
assert(!err);

if (cli_buffer.offset % BUF_SIZE || cli_buffer.offset >= BUF_SIZE * NUM_BUFFERS) {
printf("COPY|LOG: Client provided offset %X which is not buffer aligned or outside of buffer region\n", cli_buffer.offset);
err = enqueue_free(&rx_ring_cli, cli_buffer);
assert(!err);
continue;
}

err = dequeue_used(&rx_ring_mux, &mux_buffer);
assert(!err);

uintptr_t cli_addr = cli_buffer_data_region + cli_buffer.offset;
uintptr_t mux_addr = mux_buffer_data_region + mux_buffer.offset;

memcpy((void *)cli_addr, (void *)mux_addr, mux_buffer.len);
cli_buffer.len = mux_buffer.len;
mux_buffer.len = 0;

err = enqueue_used(&rx_ring_cli, cli_buffer);
assert(!err);

err = enqueue_free(&rx_ring_mux, mux_buffer);
assert(!err);

enqueued = true;
}

request_signal(rx_ring_mux.used_ring);

/* Only request signal from client if incoming packets from multiplexer are awaiting free buffers */
if (!ring_empty(rx_ring_mux.used_ring)) request_signal(rx_ring_cli.free_ring);
else cancel_signal(rx_ring_cli.free_ring);

reprocess = false;

if (!ring_empty(rx_ring_mux.used_ring) && !ring_empty(rx_ring_cli.free_ring) &&
!ring_full(rx_ring_mux.free_ring) && !ring_full(rx_ring_cli.used_ring)) {
cancel_signal(rx_ring_mux.used_ring);
cancel_signal(rx_ring_cli.free_ring);
reprocess = true;
}
}

if (enqueued && require_signal(rx_ring_cli.used_ring)) {
cancel_signal(rx_ring_cli.used_ring);
sel4cp_notify(CLIENT_CH);
}

if (enqueued && require_signal(rx_ring_mux.free_ring)) {
cancel_signal(rx_ring_mux.free_ring);
sel4cp_notify_delayed(MUX_RX_CH);
}
}

void notified(sel4cp_channel ch)
{
rx_return();
}

void init(void)
{
ring_init(&rx_ring_mux, (ring_buffer_t *)rx_free_mux, (ring_buffer_t *)rx_used_mux, NUM_BUFFERS, NUM_BUFFERS);
ring_init(&rx_ring_cli, (ring_buffer_t *)rx_free_cli, (ring_buffer_t *)rx_used_cli, NUM_BUFFERS, NUM_BUFFERS);

buffers_init(rx_ring_cli.free_ring, 0, NUM_BUFFERS, BUF_SIZE);
}
245 changes: 245 additions & 0 deletions examples/out_copy.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,245 @@
# 0 "out_copy.c"
# 0 "<built-in>"
# 0 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 0 "<command-line>" 2
# 1 "out_copy.c"


typedef unsigned long uint64_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef uint64_t size_t;
typedef uint64_t uintptr_t;


typedef unsigned char bool;
# 19 "out_copy.c"
void assert(bool b);



void *memcpy(void *dest, const void *src, size_t n);


typedef unsigned int sel4cp_channel;
void sel4cp_notify(sel4cp_channel ch);
void sel4cp_notify_delayed(sel4cp_channel ch);
# 51 "out_copy.c"
typedef struct buff_desc {
uintptr_t phys_or_offset;
uint16_t len;
void *cookie;
} buff_desc_t;


typedef struct ring_buffer {
uint32_t head;
uint32_t tail;
buff_desc_t buffers[512];
uint32_t size;
bool consumer_signalled;
} ring_buffer_t;


typedef struct ring_handle {
ring_buffer_t *free_ring;
ring_buffer_t *used_ring;
} ring_handle_t;
# 79 "out_copy.c"
static inline bool ring_empty(ring_buffer_t *ring)
{
return (ring->head == ring->tail);
}
# 91 "out_copy.c"
static inline bool ring_full(ring_buffer_t *ring)
// requires ring->size >= 1
// ensures return == {retbody}
{
return (((ring->head + 1) % ring->size) == ring->tail);
}
# 103 "out_copy.c"
static inline uint32_t ring_size(ring_buffer_t *ring)
{
return (((ring->head + ring->size) - ring->tail) % ring->size);
}
# 116 "out_copy.c"
static inline int enqueue(ring_buffer_t *ring, buff_desc_t buffer)
{
if (ring_full(ring)) return -1;

ring->buffers[ring->head].phys_or_offset = buffer.phys_or_offset;
ring->buffers[ring->head].len = buffer.len;
ring->buffers[ring->head].cookie = buffer.cookie;
if (0) ;
ring->head = (ring->head + 1) % ring->size;

return 0;
}
# 135 "out_copy.c"
static inline buff_desc_t dequeue(ring_buffer_t *ring)
{
if (ring_empty(ring)) assert(0);

buff_desc_t buffer;
buffer = ring->buffers[ring->tail];
if (0) ;
ring->tail = (ring->tail + 1) % ring->size;

return buffer;
}
# 155 "out_copy.c"
static inline int enqueue_free(ring_handle_t *ring, buff_desc_t buffer)
{
return enqueue(ring->free_ring, buffer);
}
# 168 "out_copy.c"
static inline int enqueue_used(ring_handle_t *ring, buff_desc_t buffer)
{
return enqueue(ring->used_ring, buffer);
}
# 181 "out_copy.c"
static inline buff_desc_t dequeue_free(ring_handle_t *ring)
{
return dequeue(ring->free_ring);
}
# 194 "out_copy.c"
static inline buff_desc_t dequeue_used(ring_handle_t *ring)
{
return dequeue(ring->used_ring);
}
# 208 "out_copy.c"
void ring_init(ring_handle_t *ring, ring_buffer_t *free, ring_buffer_t *used, uint32_t free_size, uint32_t used_size);
# 218 "out_copy.c"
static inline void buffers_init(ring_buffer_t *free_ring, uintptr_t base_addr, uint32_t ring_size, uint32_t buffer_size)
{
for (int i = 0; i < ring_size - 1; i++) {
buff_desc_t buffer = {(buffer_size * i) + base_addr, 0, ((void *) 0)};
int err __attribute__((unused)) = enqueue(free_ring, buffer);
assert(!err);
}
}






static inline void request_signal(ring_buffer_t *ring_buffer)
{
ring_buffer->consumer_signalled = 0;
if (0) ;
}






static inline void cancel_signal(ring_buffer_t *ring_buffer)
{
ring_buffer->consumer_signalled = 1;
if (0) ;
}






static inline bool require_signal(ring_buffer_t *ring_buffer)
{
return !ring_buffer->consumer_signalled;
}
# 269 "out_copy.c"
ring_handle_t rx_ring_mux;
ring_handle_t rx_ring_cli;


uintptr_t rx_free_mux;
uintptr_t rx_used_mux;
uintptr_t rx_free_cli;
uintptr_t rx_used_cli;


uintptr_t mux_buffer_data_region;
uintptr_t cli_buffer_data_region;

uintptr_t uart_base;

void rx_return(void)
{
bool enqueued = 0;
bool reprocess = 1;

while (reprocess) {
while (!ring_empty(rx_ring_mux.used_ring) && !ring_empty(rx_ring_cli.free_ring) &&
!ring_full(rx_ring_mux.free_ring) && !ring_full(rx_ring_cli.used_ring)) {
buff_desc_t cli_buffer, mux_buffer;
int err;
cli_buffer = dequeue_free(&rx_ring_cli);

if (cli_buffer.phys_or_offset % 2048 || cli_buffer.phys_or_offset >= 2048 * 512) {
((void) 0);
err = enqueue_free(&rx_ring_cli, cli_buffer);
assert(!err);
} else {
mux_buffer = dequeue_used(&rx_ring_mux);

uintptr_t cli_addr = cli_buffer_data_region + cli_buffer.phys_or_offset;
uintptr_t mux_addr = mux_buffer_data_region + mux_buffer.phys_or_offset;

memcpy((void *)cli_addr, (void *)mux_addr, mux_buffer.len);
cli_buffer.len = mux_buffer.len;
mux_buffer.len = 0;

err = enqueue_used(&rx_ring_cli, cli_buffer);
assert(!err);

err = enqueue_free(&rx_ring_mux, mux_buffer);
assert(!err);

enqueued = 1;
}

}

request_signal(rx_ring_mux.used_ring);


if (!ring_empty(rx_ring_mux.used_ring)) request_signal(rx_ring_cli.free_ring);
else cancel_signal(rx_ring_cli.free_ring);

reprocess = 0;

if (!ring_empty(rx_ring_mux.used_ring) && !ring_empty(rx_ring_cli.free_ring) &&
!ring_full(rx_ring_mux.free_ring) && !ring_full(rx_ring_cli.used_ring)) {
cancel_signal(rx_ring_mux.used_ring);
cancel_signal(rx_ring_cli.free_ring);
reprocess = 1;
}
}

if (enqueued && require_signal(rx_ring_cli.used_ring)) {
cancel_signal(rx_ring_cli.used_ring);
sel4cp_notify(1);
}

if (enqueued && require_signal(rx_ring_mux.free_ring)) {
cancel_signal(rx_ring_mux.free_ring);
sel4cp_notify_delayed(0);
}
}

void notified(sel4cp_channel ch)
{
rx_return();
}

void init(void)
{
ring_init(&rx_ring_mux, (ring_buffer_t *)rx_free_mux, (ring_buffer_t *)rx_used_mux, 512, 512);
ring_init(&rx_ring_cli, (ring_buffer_t *)rx_free_cli, (ring_buffer_t *)rx_used_cli, 512, 512);

buffers_init(rx_ring_cli.free_ring, 0, 512, 2048);
}
Loading

0 comments on commit b8d94d9

Please sign in to comment.