1
0
mirror of https://github.com/aolofsson/oh.git synced 2025-01-30 02:32:53 +08:00
This commit is contained in:
Andreas Olofsson 2016-01-21 13:16:59 -05:00
commit 20e0e6509c
7 changed files with 315 additions and 0 deletions

View File

@ -0,0 +1,5 @@
# mailbox tests
Kernel code here, will be included in official 'parallella-linux'
when API:s have stabilized...
https://github.com/olajep/parallella-linux/tree/wip-mailbox

33
elink/sw/mailbox-test2/build.sh Executable file
View File

@ -0,0 +1,33 @@
#!/bin/bash
set -e
ESDK=${EPIPHANY_HOME}
ELIBS="-L ${ESDK}/tools/host/lib"
EINCS="-I ${ESDK}/tools/host/include"
ELDF=${ESDK}/bsps/current/internal.ldf
# Create the binaries directory
mkdir -p bin/
if [ -z "${CROSS_COMPILE+xxx}" ]; then
case $(uname -p) in
arm*)
# Use native arm compiler (no cross prefix)
CROSS_COMPILE=
;;
*)
# Use cross compiler
CROSS_COMPILE="arm-linux-gnueabihf-"
;;
esac
fi
# Build HOST side application
${CROSS_COMPILE}gcc src/main.c -g -o bin/main.elf ${EINCS} ${ELIBS} -le-hal -le-loader -lpthread
# Build DEVICE side program
OPT=3
e-gcc -funroll-loops -g -T ${ELDF} -O${OPT} src/emain.c -o bin/emain.elf -le-lib

12
elink/sw/mailbox-test2/run.sh Executable file
View File

@ -0,0 +1,12 @@
#!/bin/bash
set -e
SCRIPT=$(readlink -f "$0")
EXEPATH=$(dirname "$SCRIPT")
cd $EXEPATH/bin
./main.elf

View File

@ -0,0 +1,13 @@
#pragma once
#include <stdint.h>
#define STEP_ADDR 0x6000
#define STOP_ADDR 0x6004
/* move to e-hal/e-lib when API is stabilized */
struct e_message {
uint32_t from;
uint32_t data;
} __attribute__((packed)) __attribute__((aligned(8)));

View File

@ -0,0 +1,53 @@
#include <e-lib.h>
#include <stdint.h>
#include "common.h"
#define MAILBOX_ADDR 0x810F0730
/* TODO: Move to e-lib */
void e_send_message(uint32_t data)
{
volatile struct e_message *mailbox = (struct e_message *) MAILBOX_ADDR;
struct e_message msg;
int i;
msg.from = e_get_coreid();
msg.data = data;
msg.from = data;
/* FIXME: 64-bit burst writes to same address is broken in FPGA elink.
* For now resort to 32-bit messages */
__asm__ __volatile__ (
"str %[msg],[%[mailbox]]"
:
: [msg] "r" (msg), [mailbox] "r" (mailbox)
: "memory");
}
int main()
{
volatile uint32_t *step = (uint32_t *) STEP_ADDR;
volatile uint32_t *stop = (uint32_t *) STOP_ADDR;
uint32_t prev_step = 0;
int i;
while (!(*stop)) {
while (prev_step == *step && !(*stop))
;
if (*stop)
break;
/* Create delay so host app have to wait */
for (i = 0; i < 100000000; i++)
__asm__ __volatile__ ("nop" ::: "memory");
e_send_message(prev_step);
prev_step++;
}
for (i = 0; i < 1000000; i++)
e_send_message(prev_step++);
}

View File

@ -0,0 +1,48 @@
#ifndef EPIPHANY_H
#define EPIPHANY_H
#include <linux/ioctl.h>
/** Length of the Global shared memory region */
#define GLOBAL_SHM_SIZE (4<<20)
#define SHM_LOCK_NAME "/eshmlock"
#define SHM_MAGIC 0xabcdef00
typedef struct _EPIPHANY_ALLOC
{
unsigned long size;
unsigned long flags;
unsigned long bus_addr; /* out */
unsigned long phy_addr; /* out */
unsigned long kvirt_addr; /* out */
unsigned long uvirt_addr; /* out */
unsigned long mmap_handle; /* Handle to use for mmap */
} epiphany_alloc_t;
struct epiphany_mailbox_msg {
__u32 from;
__u32 data;
} __attribute__((packed));
#define EPIPHANY_IOC_MAGIC 'k'
#define E_IO(nr) _IO(EPIPHANY_IOC_MAGIC, nr)
#define E_IOR(nr, type) _IOR(EPIPHANY_IOC_MAGIC, nr, type)
#define E_IOW(nr, type) _IOW(EPIPHHANY_IOC_MAGIC, nr, type)
#define E_IOWR(nr, type) _IOWR(EPIPHANY_IOC_MAGIC, nr, type)
/**
* If you add an IOC command, please update the
* EPIPHANY_IOC_MAXNR macro
*/
#define EPIPHANY_IOC_GETSHM_CMD 24
#define EPIPHANY_IOC_MAILBOX_READ_CMD 25
#define EPIPHANY_IOC_MAILBOX_COUNT_CMD 26
#define EPIPHANY_IOC_MAXNR 26
#define EPIPHANY_IOC_GETSHM E_IOWR(EPIPHANY_IOC_GETSHM_CMD, epiphany_alloc_t *)
#define EPIPHANY_IOC_MAILBOX_READ E_IOWR(EPIPHANY_IOC_MAILBOX_READ_CMD, struct epiphany_mailbox_msg)
#define EPIPHANY_IOC_MAILBOX_COUNT E_IO(EPIPHANY_IOC_MAILBOX_COUNT_CMD)
#endif

View File

@ -0,0 +1,151 @@
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <stdint.h>
#include <time.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <e-hal.h>
#include <stdbool.h>
#include <errno.h>
#include <linux/types.h>
#include "epiphany.h"
#include "common.h"
/* TODO: Include in e-hal API */
int e_mailbox_read(struct e_message *msg, int flags)
{
int fd, rc;
struct epiphany_mailbox_msg kernel_msg;
flags &= O_NONBLOCK;
fd = open("/dev/epiphany", flags, O_RDONLY);
if (fd < 0)
return fd;
rc = ioctl(fd, EPIPHANY_IOC_MAILBOX_READ, &kernel_msg);
if (rc) {
close(fd);
return rc;
}
#if 0
msg->from = kernel_msg.from;
msg->data = kernel_msg.data;
#else
/* work around FPGA Elink 64-bit burst bug
* Message can only be 32-bits for now so use lower bits for data
* and let sender be 0 */
msg->from = 0;
msg->data = kernel_msg.from;
#endif
close(fd);
return 0;
}
int e_mailbox_count()
{
int fd, rc;
fd = open("/dev/epiphany", 0, O_RDONLY);
if (fd < 0)
return fd;
rc = ioctl(fd, EPIPHANY_IOC_MAILBOX_COUNT);
close(fd);
return rc;
}
int main(int argc, char *argv[])
{
unsigned rows, cols, i, count;
const uint32_t one = 1, zero = 0;
uint32_t step = 1;
e_platform_t platform;
e_epiphany_t dev;
int expected, received, errors;
double time, rate;
struct timespec start, stop;
struct e_message msg = { 0, 0 };
// initialize system, read platform params from
// default HDF. Then, reset the platform and
// get the actual system parameters.
e_init(NULL);
e_reset_system();
e_get_platform_info(&platform);
//open the workgroup
rows = platform.rows;
cols = platform.cols;
e_open(&dev, 0, 0, rows, cols);
//load the device program on the board
e_load_group("emain.elf", &dev, 0, 0, 1, 1, E_FALSE);
e_write(&dev, 0, 0, STOP_ADDR, &zero, sizeof(zero));
e_write(&dev, 0, 0, STEP_ADDR, &zero, sizeof(zero));
e_start_group(&dev);
/* Test blocking wait with interrupts */
printf("Testing blocking wait with interrupts\n");
for (i = 0; i < 16; i++) {
e_write(&dev, 0, 0, STEP_ADDR, &step, sizeof(step));
step++;
/* Blocking wait while Epiphany performs dummy loop */
e_mailbox_read(&msg, 0);
printf("i: %.2d from: 0x%08x data: 0x%08x\n",
i, msg.from, msg.data);
}
e_write(&dev, 0, 0, STOP_ADDR, &one, sizeof(one));
/* Test reading using count */
expected = 1000000;
received = 0;
errors = 0;
printf("\nReading %d messages\n", expected);
clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start);
count = e_mailbox_count();
while (count >= 0 && !errors && received < expected) {
if (!count)
sched_yield();
while (count--) {
if (!e_mailbox_read(&msg, 0))
received++;
else
errors++;
}
count = e_mailbox_count();
}
clock_gettime(CLOCK_THREAD_CPUTIME_ID, &stop);
time = (double) (stop.tv_sec - start.tv_sec) +
(double) (stop.tv_nsec - start.tv_nsec) / 1000000000.0;
rate = (double) expected / time;
printf("received: %d\terrors: %d\ttime: %3.2fs\trate: %d msgs/s\n",
received, errors, time, (int) rate);
e_close(&dev);
e_finalize();
}