minidol: initial commit
authorSebastian <basti@sraa.de>
Wed, 9 Oct 2013 13:39:39 +0000 (15:39 +0200)
committerSebastian <basti@sraa.de>
Wed, 9 Oct 2013 13:39:39 +0000 (15:39 +0200)
Simple DOL-application consisting of the two blocks "Gen" (generate
a sequence of numbers) and "Square" (squares numbers) including the
block wrappers, DOL communication liberary, host application and
build system.

Buffer sizes are defined in shared.h and hsrc/main.c, ports are
assigned to buffers in the wrappers. Buffers are located in shared
memory (external DRAM).

The files shared.h, lib/*_Wrapper.c and hsrc/main.c will need to be
generated by the DOL toolchain; all other files are static.

15 files changed:
minidol/Makefile
minidol/esrc/Gen.c [new file with mode: 0644]
minidol/esrc/Gen.h [new file with mode: 0644]
minidol/esrc/Square.c [new file with mode: 0644]
minidol/esrc/Square.h [new file with mode: 0644]
minidol/hsrc/main.c [new file with mode: 0644]
minidol/lib/Gen_Wrapper.c [new file with mode: 0644]
minidol/lib/Square_Wrapper.c [new file with mode: 0644]
minidol/lib/dol.c [new file with mode: 0644]
minidol/lib/dol.h [new file with mode: 0644]
minidol/lib/index.c [new file with mode: 0644]
minidol/lib/index.h [new file with mode: 0644]
minidol/lib/ports.c [new file with mode: 0644]
minidol/lib/ports.h [new file with mode: 0644]
minidol/shared.h [new file with mode: 0644]

index 8fe07a310a0ce0c9034b9a7f80e7587285bc6d28..12738f4a325d8bcc6771bdcacd5958aacdbb08a2 100644 (file)
@@ -17,20 +17,20 @@ HOSTAPP     = $(DEST)/ep_application
 HOBJS  = $(HDEST)/main.o
 
 # Epiphany applications and common objects
-EPAPPS = $(DEST)/Beam_Former.srec
+EPAPPS = $(DEST)/Gen.srec $(DEST)/Square.srec #$(DEST)/Beam_Former.srec
 EWRAPPERS = $(patsubst $(DEST)%,$(EDEST)%,$(EPAPPS:.srec=_Wrapper.o))
-ECOMMON        = $(EDEST)/dol.o $(EDEST)/buffers.o
+ECOMMON        = $(EDEST)/dol.o $(EDEST)/ports.o $(EDEST)/index.o
 
 # Epiphany build flags
 CC     = e-gcc
 OBJCOPY        = e-objcopy
-CFLAGS = -O2 -falign-loops=8 -falign-functions=8 -Wall -Ilib
+CFLAGS = -O2 -std=c99 -Ilib -falign-loops=8 -falign-functions=8 -Wall
 LFLAGS = -T$(EPIPHANY_HOME)/bsps/current/fast.ldf -le-lib
 OCFLAGS        = -R .shared_dram -R .data_bank3
 
 # Host build flags
 HOSTCC = gcc
-HCFLAGS        = -I$(EPIPHANY_HOME)/tools/host/include -std=c99 -Wall
+HCFLAGS        = -O2 -std=c99 -I$(EPIPHANY_HOME)/tools/host/include -Wall
 HLFLAGS        = -L$(EPIPHANY_HOME)/tools/host/lib -le-hal
 
 # Global rules
diff --git a/minidol/esrc/Gen.c b/minidol/esrc/Gen.c
new file mode 100644 (file)
index 0000000..133e5aa
--- /dev/null
@@ -0,0 +1,28 @@
+#include <stdio.h>
+#include "Gen.h"
+
+void Gen_delay(void)
+{
+       for(volatile int a = 0; a < 50; a++)
+               for(volatile int b = 0; b < 2000000; b++)
+                       ;
+}
+
+void Gen_init(DOLProcess *p) {
+       ((Gen_State*)p->local)->index = 0;
+}
+
+int Gen_fire(DOLProcess *p) {
+       float i;
+
+       if (p->local->index < LENGTH) {
+Gen_delay();
+               p->local->index++;
+               i = p->local->index;
+               DOL_write(PORT_OUTPUT, &i, sizeof(float), p);
+       } else {
+               DOL_detach(p);
+       }
+
+       return 0;
+}
diff --git a/minidol/esrc/Gen.h b/minidol/esrc/Gen.h
new file mode 100644 (file)
index 0000000..9acfcf5
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef GEN_H
+#define GEN_H
+
+#include <dol.h>
+
+#define PORT_OUTPUT "0"
+
+#define LENGTH 8
+
+typedef struct _local_states {
+       int index;
+} Gen_State;
+
+void Gen_init(DOLProcess *);
+int Gen_fire(DOLProcess *);
+
+#endif
diff --git a/minidol/esrc/Square.c b/minidol/esrc/Square.c
new file mode 100644 (file)
index 0000000..017f19f
--- /dev/null
@@ -0,0 +1,31 @@
+#include <stdio.h>
+#include "Square.h"
+
+#include "../shared.h"
+extern shm_t shm;
+
+void Square_delay(void)
+{
+       for(volatile int a = 0; a < 25; a++)
+               for(volatile int b = 0; b < 25; b++)
+                       ;
+}
+
+void Square_init(DOLProcess *p) {
+       ((Square_State*)p->local)->index = 0;
+}
+
+int Square_fire(DOLProcess *p) {
+       float i;
+
+       if (((Square_State*)p->local)->index < LENGTH) {
+               DOL_read(PORT_INPUT, &i, sizeof(float), p);
+               i = i*i;
+               DOL_write(PORT_OUTPUT, &i, sizeof(float), p);
+               ((Square_State*)p->local)->index++;
+       } else {
+               DOL_detach(p);
+       }
+
+       return 0;
+}
diff --git a/minidol/esrc/Square.h b/minidol/esrc/Square.h
new file mode 100644 (file)
index 0000000..cb89096
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef SQUARE_H
+#define SQUARE_H
+
+#include <dol.h>
+
+#define PORT_INPUT "0"
+#define PORT_OUTPUT "1"
+
+#define LENGTH 8
+
+typedef struct _local_states {
+       int index;
+} Square_State;
+
+void Square_init(DOLProcess *);
+int Square_fire(DOLProcess *);
+
+#endif
diff --git a/minidol/hsrc/main.c b/minidol/hsrc/main.c
new file mode 100644 (file)
index 0000000..c8fc6e0
--- /dev/null
@@ -0,0 +1,165 @@
+/* Epiphany Host Application */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <time.h>
+
+#include "e-hal.h"
+
+/* common data structures */
+#include "../shared.h"
+
+#define FAIL(...) { fprintf(stderr, __VA_ARGS__); exit(1); }
+#define SHM_OFFSET 0x01000000
+
+#define ROW(X) (X/4)
+#define COL(X) (X%4)
+
+#define NUM_PROGRAMS   2
+
+/* programs to run */
+char programs[NUM_PROGRAMS][64] = {
+       "bin/Square.srec",
+       "bin/Gen.srec",
+};
+
+/* local copy of shared memory */
+shm_t  shm = {{ 0 }};
+
+#if 0
+static uint32_t xorshift32(void)
+{
+       static uint32_t x = 314159265;
+       x ^= x << 17;
+       x ^= x >> 13;
+       x ^= x << 5;
+       return(x);
+}
+#endif
+
+void shm_init(void) {
+       /* input data */
+       shm.buf0.size = 8;
+       shm.buf0.rp = 0;
+       shm.buf0.wp = 0;
+
+       /* output data */
+       shm.buf1.size = 32;
+       shm.buf1.rp   = 0;
+       shm.buf1.wp   = 0;
+}
+
+int main(int argc, char *argv[])
+{
+       char filename[255];     /* filename to load */
+
+       /* core states */
+       int32_t states[NUM_CORES]     = { 0 };
+       int32_t laststates[NUM_CORES] = { 0 };
+
+       e_epiphany_t dev;
+       e_mem_t      emem;
+
+       e_set_host_verbosity(H_D0);
+       e_set_loader_verbosity(L_D0);
+
+       /* init board, reset epiphany, open workgroup */
+       if(e_init(NULL) != E_OK)
+               FAIL("Can't init!\n");
+       e_reset_system();
+       if(e_open(&dev, 0, 0, 4, 4) != E_OK)
+               FAIL("Can't open!\n");
+
+       /* initialize, allocate and update shared memory buffer */
+       shm_init();
+       if(e_alloc(&emem, SHM_OFFSET, sizeof(shm_t)) != E_OK)
+               FAIL("Can't alloc!\n");
+       if(e_write(&emem, 0, 0, (off_t)0, &shm, sizeof(shm_t)) == E_ERR)
+               FAIL("Can't clear shm!\n");
+       if(e_write(&emem, 0, 0, (off_t)0, &states, sizeof(states)) == E_ERR)
+               FAIL("Can't clear states!\n");
+
+       /* load and start all programs */
+       for(int i = 0; i < NUM_PROGRAMS; i++) {
+               snprintf(filename, 255, "%s", programs[i]);
+               printf("Kicking core %i = (%i, %i) with '%s'\n",
+                       i, ROW(i), COL(i), filename);
+               if(e_load(filename, &dev, ROW(i), COL(i), E_TRUE) != E_OK)
+                       FAIL("Can't load %i!\n", i);
+       }
+
+       /* =============================================================== */
+       printf("Started %i cores.\n", NUM_PROGRAMS);
+       while(1) {
+               int done = 1;
+
+               /* poll shm states for changes */
+               printf("Polling shared memory.\n");
+
+               while(1) {
+                       /* read epiphany core states */
+                       if(e_read(&emem, 0, 0, (off_t)0, &states,
+                               sizeof(states)) == E_ERR)
+                                       FAIL("Can't poll!\n");
+
+                       /* check for state changes */
+                       if(memcmp(laststates, states, sizeof(states)))
+                               break;
+               };
+
+               /* save current states */
+               memcpy(laststates, states, sizeof(states));
+
+               /* print core states */
+               for(int i = 0; i < NUM_PROGRAMS; i++) {
+                       printf("CORE %i: ", i);
+                       switch(states[i]) {
+                       case -1: printf("done "); break;
+                       default: printf("state %i ", states[i]); done=0; break;
+                       }
+                       printf("\n");
+               }
+               printf("CORE14: 0x%x\n", states[14]);
+               printf("CORE15: 0x%x\n", states[15]);
+
+               /* stop polling if all cores finished */
+               if(done) break;
+       }
+       /* =============================================================== */
+
+       printf("All cores finished.\n");
+
+       /* read whole shm buffer */
+       if(e_read(&emem, 0, 0, (off_t)0, &shm, sizeof(shm)) == E_ERR)
+               FAIL("Can't read full shm!\n");
+
+       /* print buffer 0 and buffer 1 */
+       for(int i = 0; i < 16; i++) {
+               printf("0x%x ", shm.buf0.buf[i]);
+       } printf("\n");
+       for(int i = 0; i < 16; i++) {
+               printf("0x%x ", shm.buf1.buf[i]);
+       } printf("\n");
+
+
+       for(int i = 0; i < 4; i++) {
+               printf("%.2f\t", ((float*)shm.buf0.buf)[i]);
+       } printf("\n");
+
+       for(int i = 0; i < 8; i++) {
+               printf("%.2f\t", ((float*)shm.buf1.buf)[i]);
+       } printf("\n");
+
+       /* free shm buffer, close workgroup and finalize */
+       if(e_free(&emem) != E_OK)
+               FAIL("Can't free!\n");
+       if(e_close(&dev) != E_OK)
+               FAIL("Can't close!\n");
+       if(e_finalize() != E_OK)
+               FAIL("Can't finalize!\n");
+
+       return(0);
+}
+
diff --git a/minidol/lib/Gen_Wrapper.c b/minidol/lib/Gen_Wrapper.c
new file mode 100644 (file)
index 0000000..88eb4c3
--- /dev/null
@@ -0,0 +1,68 @@
+/* Gen_Wrapper
+ * ===================================================================== */
+#include <e_lib.h>
+#include <string.h>
+#include "../esrc/Gen.h"
+#include "../shared.h"
+#include "ports.h"
+#include "index.h"
+
+shm_t shm SECTION(".shared_dram");
+
+/* DOL structures
+ * ===================================================================== */
+struct _DOL_wptr Gen_wptr = {
+       1,              /* active   */
+       {0,0,0,0}       /* instance */
+};
+
+Gen_State Gen_local;
+DOLProcess Gen_process = {
+       &Gen_local,
+       &Gen_init,
+       &Gen_fire,
+       &Gen_wptr,
+};
+
+/* Port Read/Write Functions
+ * ===================================================================== */
+int size_0 (void)               { return(size_shm (&shm.buf0)); }
+int level_0(void)               { return(level_shm(&shm.buf0)); }
+int read_0 (void *buf, int len) { return(read_shm (&shm.buf0, buf, len)); }
+int write_0(void *buf, int len) { return(write_shm(&shm.buf0, buf, len)); }
+
+/* Port Mapping
+ * ===================================================================== */
+#define NUM_PORTS 1
+port_t ports[NUM_PORTS] = {
+       { "0", size_0, level_0, NULL, write_0},
+};
+
+port_t *get_port(void *port)
+{
+       for(int i = 0; i < NUM_PORTS; i++) {
+               if(!strncmp(ports[i].name, port, PORTNAME_MAXLEN)) {
+                       /* found the port */
+                       return(&ports[i]);
+               }
+       }
+       return(NULL);
+}
+
+/* eCore entry point
+ * ===================================================================== */
+int main(void)
+{
+       int index = core_id2lin(e_get_coreid());
+       int state = 0;
+
+       Gen_process.init((struct _DOLProcess_struct*)&Gen_process);
+       while(Gen_process.wptr->active) {
+               shm.states[index] = ++state;
+               Gen_process.fire((struct _DOLProcess_struct*)&Gen_process);
+       }
+
+       shm.states[index] = -1;
+       while(1);
+}
+
diff --git a/minidol/lib/Square_Wrapper.c b/minidol/lib/Square_Wrapper.c
new file mode 100644 (file)
index 0000000..b28f924
--- /dev/null
@@ -0,0 +1,73 @@
+/* Square_Wrapper
+ * ===================================================================== */
+#include <e_lib.h>
+#include <string.h>
+#include "../esrc/Square.h"
+#include "../shared.h"
+#include "ports.h"
+#include "index.h"
+
+shm_t shm SECTION(".shared_dram");
+
+/* DOL structures
+ * ===================================================================== */
+struct _DOL_wptr Square_wptr = {
+       1,              /* active   */
+       {0,0,0,0}       /* instance */
+};
+
+Square_State Square_local;
+DOLProcess Square_process = {
+       &Square_local,
+       &Square_init,
+       &Square_fire,
+       &Square_wptr,
+};
+
+/* Port Read/Write Functions
+ * ===================================================================== */
+int size_0 (void)               { return(size_shm (&shm.buf0)); }
+int level_0(void)               { return(level_shm(&shm.buf0)); }
+int read_0 (void *buf, int len) { return(read_shm (&shm.buf0, buf, len)); }
+int write_0(void *buf, int len) { return(write_shm(&shm.buf0, buf, len)); }
+int size_1 (void)               { return(size_shm (&shm.buf1)); }
+int level_1(void)               { return(level_shm(&shm.buf1)); }
+int read_1 (void *buf, int len) { return(read_shm (&shm.buf1, buf, len)); }
+int write_1(void *buf, int len) { return(write_shm(&shm.buf1, buf, len)); }
+
+/* Port Mapping
+ * ===================================================================== */
+#define NUM_PORTS 2
+port_t ports[NUM_PORTS] = {
+       { "0", size_0, level_0, read_0, NULL    },
+       { "1", size_1, level_1, NULL,   write_1 },
+};
+
+port_t *get_port(void *port)
+{
+       for(int i = 0; i < NUM_PORTS; i++) {
+               if(!strncmp(ports[i].name, port, PORTNAME_MAXLEN)) {
+                       /* found the port */
+                       return(&ports[i]);
+               }
+       }
+       return(NULL);
+}
+
+/* eCore entry point
+ * ===================================================================== */
+int main(void)
+{
+       int index = core_id2lin(e_get_coreid());
+       int state = 0;
+
+       Square_process.init((struct _DOLProcess_struct*)&Square_process);
+       while(Square_process.wptr->active) {
+               shm.states[index] = ++state;
+               Square_process.fire((struct _DOLProcess_struct*)&Square_process);
+       }
+
+       shm.states[index] = -1;
+       while(1);
+}
+
diff --git a/minidol/lib/dol.c b/minidol/lib/dol.c
new file mode 100644 (file)
index 0000000..fed6ca4
--- /dev/null
@@ -0,0 +1,94 @@
+/* DOL Block Implementation */
+
+#include <stdio.h>
+#include <dol.h>
+#include "ports.h"
+
+/* DOL support functions
+ * ===================================================================== */
+int DOL_read(void *port, void *buf, int len, DOLProcess *p)
+{
+       port_t *pp = get_port(port);
+       if(!pp || !pp->read) return 0;
+
+       return(pp->read(buf, len));
+}
+
+int DOL_write(void *port, void *buf, int len, DOLProcess *p)
+{
+       port_t *pp = get_port(port);
+       if(!pp || !pp->write) return 0;
+
+       return(pp->write(buf, len));
+}
+
+int DOL_rtest(void *port, int len, DOLProcess *p)
+{
+       /* check if channel contains at least 'len' bytes */
+       port_t *pp = get_port(port);
+       if(!pp || !pp->level) return 0;
+
+       int level = pp->level();
+       return (level >= len) ? 1 : 0;
+}
+
+int DOL_wtest(void *port, int len, DOLProcess *p)
+{
+       /* check if channel has space for at least 'len' bytes */
+       port_t *pp = get_port(port);
+       if(!pp || !pp->level) return 0;
+
+       int level = pp->level();
+       return (level < (pp->size() - len)) ? 1 : 0;
+}
+
+void DOL_detach(DOLProcess *p)
+{
+       p->wptr->active = 0;
+       return;
+}
+
+int DOL_get_index(int dim, DOLProcess *p)
+{
+       if((dim < 0) || (dim > 4)) return(-1);
+
+       return(p->wptr->instance[dim]);
+}
+
+char* DOL_create_port(char* port, char* base, int ndim, int index0, int range0,
+       int index1, int range1, int index2, int range2, int index3, int range3)
+{
+       /* hang on invalid input */
+       if(range0 && (index0 >= range0)) while(1);
+       if(range1 && (index1 >= range1)) while(1);
+       if(range2 && (index2 >= range2)) while(1);
+       if(range3 && (index3 >= range3)) while(1);
+
+       switch(ndim) {
+       case 1:
+               snprintf(port, PORTNAME_MAXLEN-1,
+                       "%s_%i", base, index0);
+               port[PORTNAME_MAXLEN-1] = '\0';
+               break;
+       case 2:
+               snprintf(port, PORTNAME_MAXLEN-1,
+                       "%s_%i_%i", base, index0, index1);
+               port[PORTNAME_MAXLEN-1] = '\0';
+               break;
+       case 3:
+               snprintf(port, PORTNAME_MAXLEN-1,
+                       "%s_%i_%i_%i", base, index0, index1, index2),
+               port[PORTNAME_MAXLEN-1] = '\0';
+               break;
+       case 4:
+               snprintf(port, PORTNAME_MAXLEN-1,
+                       "%s_%i_%i_%i_%i", base, index0, index1, index2, index3);
+               port[PORTNAME_MAXLEN-1] = '\0';
+               break;
+       default:
+               while(1);
+       }
+
+       return(port);
+}
+
diff --git a/minidol/lib/dol.h b/minidol/lib/dol.h
new file mode 100644 (file)
index 0000000..f8424d1
--- /dev/null
@@ -0,0 +1,66 @@
+/* DOL Block Header */
+#ifndef _DOL_H_
+#define _DOL_H_
+
+/* defined by the blocks */
+typedef struct _local_states *LocalState;
+
+/* process functions */
+struct _DOLProcess_struct;
+typedef void (*ProcessInit)(struct _DOLProcess_struct*);
+typedef int  (*ProcessFire)(struct _DOLProcess_struct*);
+
+/* WPTR definition */
+struct _DOL_wptr {
+       int active;
+       int instance[4];
+};
+typedef struct _DOL_wptr *WPTR;
+
+/* DOL process */
+typedef struct _DOLProcess_struct {
+       LocalState      local;
+       ProcessInit     init;
+       ProcessFire     fire;
+       WPTR            wptr;
+} DOLProcess;
+
+/* DOL-specific functions */
+int  DOL_read (void*, void*, int, DOLProcess*);
+int  DOL_write(void*, void*, int, DOLProcess*);
+int  DOL_rtest(void*, int, DOLProcess*);
+int  DOL_wtest(void*, int, DOLProcess*);
+void DOL_detach(DOLProcess*);
+#define GETINDEX(dim) DOL_get_index(dim, p)
+int  DOL_get_index(int, DOLProcess*);
+
+/* port generation */
+#define PORTNAME_MAXLEN 64
+#define CREATEPORTVAR(name) char name[PORTNAME_MAXLEN]
+
+#define CREATEPORT_FUNCTION(_1, _2, _3, _4, _5, \
+       _6, _7, _8, _9, _10, _11, NAME, ...) NAME
+#define CREATEPORT(...) CREATEPORT_FUNCTION(__VA_ARGS__, \
+       CREATEPORT_4, CREATEPORT_BAD_PARAMETERS, \
+       CREATEPORT_3, CREATEPORT_BAD_PARAMETERS, \
+       CREATEPORT_2, CREATEPORT_BAD_PARAMETERS, \
+       CREATEPORT_1, CREATEPORT_BAD_PARAMETERS, \
+       CREATEPORT_BAD_PARAMETERS, CREATEPORT_BAD_PARAMETERS, \
+       CREATEPORT_BAD_PARAMETERS, CREATEPORT_BAD_PARAMETERS)(__VA_ARGS__)
+
+#define CREATEPORT_1(port, base, ndim, i0, r0) \
+       DOL_create_port(port, base, ndim, i0, r0, 0, 0, 0, 0, 0, 0)
+
+#define CREATEPORT_2(port, base, ndim, i0, r0, i1, r1) \
+       DOL_create_port(port, base, ndim, i0, r0, i1, r1, 0, 0, 0, 0)
+
+#define CREATEPORT_3(port, base, ndim, i0, r0, i1, r1, i2, r2) \
+       DOL_create_port(port, base, ndim, i0, r0, i1, r1, i2, r2, 0, 0)
+
+#define CREATEPORT_4(port, base, ndim, i0, r0, i1, r1, i2, r2, i3, r3) \
+       DOL_create_port(port, base, ndim, i0, r0, i1, r1, i2, r2, i3, r3)
+
+char* DOL_create_port(char*, char*, int,
+       int, int, int, int, int, int, int, int);
+
+#endif /* _DOL_H_ */
diff --git a/minidol/lib/index.c b/minidol/lib/index.c
new file mode 100644 (file)
index 0000000..4841b7d
--- /dev/null
@@ -0,0 +1,20 @@
+/* index.c: some index calculations */
+
+#include <stdint.h>
+
+#include "e_lib.h"
+
+/* some defines */
+#define CORE0          0x808   /* coreid of first core */
+#define CORES_PER_ROW  4       /* cores per row - 4 on E16G3 */
+
+uint32_t core_id2lin(e_coreid_t coreid)
+{      /* take coreid, return linear index */
+       return((coreid-CORE0) / (64/CORES_PER_ROW) + (coreid-CORE0)%64);
+}
+
+uint32_t core_lin2id(uint32_t eidx)
+{      /* take linear index, return coreid */
+       return(64 * eidx / CORES_PER_ROW + eidx % CORES_PER_ROW + CORE0);
+}
+
diff --git a/minidol/lib/index.h b/minidol/lib/index.h
new file mode 100644 (file)
index 0000000..6327333
--- /dev/null
@@ -0,0 +1,11 @@
+/* index.h */
+#ifndef _INDEX_H_
+#define _INDEX_H_
+
+#include "e_lib.h"
+
+/* core id <-> linear id conversion */
+uint32_t core_id2lin(e_coreid_t id);
+uint32_t core_lin2id(uint32_t lin);
+
+#endif /* _INDEX_H_ */
diff --git a/minidol/lib/ports.c b/minidol/lib/ports.c
new file mode 100644 (file)
index 0000000..3ae1ece
--- /dev/null
@@ -0,0 +1,80 @@
+/* ports implementation */
+#include <string.h>
+
+#include "../shared.h"
+
+extern shm_t shm;
+#define DEBUG0(X) { shm.states[14] = (uint32_t)(X); }
+#define DEBUG1(X) { shm.states[15] = (uint32_t)(X); }
+
+void delay()
+{
+       for(volatile long a = 0; a < 25; a++)
+               for(volatile long b = 0; b < 2000000; b++)
+                       ;
+}
+
+int size_shm(void *hwbuf)
+{
+       hwbuf_t *b = (hwbuf_t*)hwbuf;
+       return(b->size);
+}
+
+int level_shm(void *hwbuf)
+{
+       hwbuf_t *b = (hwbuf_t*)hwbuf;
+
+       int level = (b->wp - b->rp) % b->size;
+       if(level < 0) level += b->size;
+
+       return(level);
+}
+
+int read_shm (void *hwbuf, void *buf, int len)
+{
+       hwbuf_t *b = (hwbuf_t*)hwbuf;
+
+       /* block if necessary */
+       while(level_shm(hwbuf) < len);
+
+       /* copy data */
+       if(b->rp + len > b->size) {
+               /* wrap-around -> split access */
+               uint32_t amount = b->size - b->rp;
+               memcpy(buf, &b->buf[b->rp], amount);
+               memcpy(buf + amount, &b->buf[0], len - amount);
+       } else {
+               memcpy(buf, &b->buf[b->rp], len);
+       }
+
+       /* update read pointer */
+       b->rp = (b->rp + len) % b->size;
+
+       return(len);
+}
+
+int write_shm(void *hwbuf, void *buf, int len)
+{
+       hwbuf_t *b = (hwbuf_t*)hwbuf;
+
+       /* block if necessary */
+       while(b->size - level_shm(hwbuf) < len);
+
+       /* copy data */
+       if(b->wp + len > b->size) {
+               /* wrap-around -> split access */
+               uint32_t amount = b->size - b->wp;
+               memcpy(&b->buf[b->wp], buf, amount);
+               memcpy(&b->buf[0], buf + amount, len - amount);
+       } else {
+               memcpy(&b->buf[b->wp], buf, len);
+       }
+
+       /* update write pointer */
+       b->wp = (b->wp + len) % b->size;
+
+DEBUG1(level_shm(hwbuf)); delay();
+
+       return(len);
+}
+
diff --git a/minidol/lib/ports.h b/minidol/lib/ports.h
new file mode 100644 (file)
index 0000000..7561572
--- /dev/null
@@ -0,0 +1,24 @@
+/* ports header */
+#ifndef _PORTS_H_
+#define _PORTS_H_
+
+#include <unistd.h>
+#include <dol.h>
+
+typedef struct {
+       char  name[PORTNAME_MAXLEN];
+       int   (*size) (void);   /* size */
+       int   (*level)(void);   /* how many bytes in buf? */
+       int   (*read) (void *buf, int len);
+       int   (*write)(void *buf, int len);
+} port_t;
+
+port_t* get_port(void* port);
+
+int size_shm (void *hwbuf);
+int level_shm(void *hwbuf);
+int read_shm (void *hwbuf, void *buf, int len);
+int write_shm(void *hwbuf, void *buf, int len);
+
+#endif /* _PORTS_H_ */
+
diff --git a/minidol/shared.h b/minidol/shared.h
new file mode 100644 (file)
index 0000000..032ef33
--- /dev/null
@@ -0,0 +1,46 @@
+/* shared.h
+ * NOTE: shared between Host and Epiphany */
+#ifndef _SHARED_H_
+#define _SHARED_H_
+
+#ifndef PACKED
+#define PACKED __attribute__((packed))
+#endif
+
+#include <stdint.h>
+
+#define NUM_CORES 16
+
+typedef struct {
+       volatile uint32_t rp;
+       volatile uint32_t wp;
+       volatile uint32_t size;
+       char     buf[];
+} PACKED hwbuf_t;
+
+typedef struct {
+       uint32_t rp;
+       uint32_t wp;
+       uint32_t size;
+       char     buf[8];
+} PACKED buf0_t;
+
+typedef struct {
+       uint32_t rp;
+       uint32_t wp;
+       uint32_t size;
+       char     buf[32];
+} PACKED buf1_t;
+
+typedef struct {
+       uint32_t counters[2];
+} PACKED coredata_t;
+
+typedef struct {
+       int32_t    states[NUM_CORES];
+       coredata_t cores[NUM_CORES];
+       buf0_t     buf0;
+       buf1_t     buf1;
+} PACKED shm_t;
+
+#endif /* _SHARED_H_ */