mirror of
https://github.com/aolofsson/oh.git
synced 2025-01-30 02:32:53 +08:00
Merge branch 'master' of https://github.com/parallella/oh
This commit is contained in:
commit
20e0e6509c
5
elink/sw/mailbox-test2/README.md
Normal file
5
elink/sw/mailbox-test2/README.md
Normal 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
33
elink/sw/mailbox-test2/build.sh
Executable 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
12
elink/sw/mailbox-test2/run.sh
Executable file
@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT=$(readlink -f "$0")
|
||||
EXEPATH=$(dirname "$SCRIPT")
|
||||
|
||||
|
||||
cd $EXEPATH/bin
|
||||
|
||||
./main.elf
|
||||
|
13
elink/sw/mailbox-test2/src/common.h
Normal file
13
elink/sw/mailbox-test2/src/common.h
Normal 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)));
|
||||
|
53
elink/sw/mailbox-test2/src/emain.c
Normal file
53
elink/sw/mailbox-test2/src/emain.c
Normal 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++);
|
||||
}
|
48
elink/sw/mailbox-test2/src/epiphany.h
Normal file
48
elink/sw/mailbox-test2/src/epiphany.h
Normal 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
|
151
elink/sw/mailbox-test2/src/main.c
Normal file
151
elink/sw/mailbox-test2/src/main.c
Normal 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();
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user