Commit 9a4fabc1 authored by Grzegorz Daniluk's avatar Grzegorz Daniluk

Merge branch 'wr-starting-kit' into proposed_master

parents 97c2f4b9 3c9b25b8
[submodule "ppsi"]
path = ppsi
url = git://ohwr.org/white-rabbit/ppsi.git
url = https://ohwr.org/project/ppsi.git
......@@ -127,8 +127,17 @@ config P2P
If you deny this option, P2P code is not built, to save some
binary size.
config IP
config WR_NIC_CPU
depends on WR_NODE
boolean "Allows compatibility with external NIC driver on CPU"
default n
help
ARP & ICMP traffic are bypassed to the external fabric (NIC) so
that the CPU handles these packets and not the LM32. (This option
is mainly used by the wr-starting-kit on SPEC cards)
config IP
depends on WR_NODE && !WR_NIC_CPU
boolean "Compile minimal IP support in wrpc-sw"
help
This allows to run LM32 code that is aware of IP. The feature is
......@@ -313,7 +322,7 @@ config ABSCAL
described and documented by Peter Jansweijer.
config LLDP
depends on WR_NODE
depends on WR_NODE && IP
boolean "Include LLDP protocol transmit-only"
default n
help
......
......@@ -24,21 +24,18 @@ CONFIG_PPSI=y
CONFIG_W1=y
CONFIG_LATENCY_ETHTYPE=291
# CONFIG_P2P is not set
CONFIG_IP=y
CONFIG_WR_NIC_CPU=y
# CONFIG_CMD_CONFIG is not set
# CONFIG_SYSLOG is not set
CONFIG_SNMP=y
CONFIG_SNMP_SET=y
CONFIG_BUILD_INIT=y
CONFIG_INIT_COMMAND="vlan off;ptp stop;sfp match;mode slave;ptp start"
CONFIG_HAS_BUILD_INIT=1
CONFIG_HAS_FLASH_INIT=1
CONFIG_FLASH_INIT=y
# CONFIG_AUX_DIAG is not set
CONFIG_AUX_DIAG=y
CONFIG_SDB_STORAGE=y
CONFIG_GENSDBFS=y
# CONFIG_LEGACY_EEPROM is not set
# CONFIG_WR_DIAG is not set
CONFIG_WR_DIAG=y
# CONFIG_WR_NODE_SIM is not set
CONFIG_ABSCAL=y
......
......@@ -433,13 +433,18 @@ you would have to install it manually. E.g. in Ubuntu, please install
First, you need to download and unpack the LM32 toolchain from the location
mentioned in section \ref{Repositories and Releases}. The following example
uses 32bit version of a toolchain. If you encounter problems running it, please
use 64bit version.
uses 32bit version of a toolchain.
\begin{lstlisting}
$ wget http://www.ohwr.org/attachments/download/1133/lm32.tar.xz
$ wget https://www.ohwr.org/project/wrpc-sw/uploads/a2e8eeba448fbc8d580e68004e6f6c7f/lm32.tar.xz
$ tar xJf lm32.tar.xz -C <your_location>
\end{lstlisting}
If you encounter problems running it, please use the 64bit version.
\begin{lstlisting}
$ wget https://www.ohwr.org/project/wrpc-sw/uploads/2776ce0ba43503d1486ae205b48fb450/lm32_host_64bit.tar.xz
$ tar xJf lm32_host_64bit.tar.xz -C <your_location>
\end{lstlisting}
Then you need to set a \texttt{CROSS\_COMPILE} environment variable in order
to compile the software for the LM32 processor:
\begin{lstlisting}
......@@ -531,7 +536,8 @@ $ make
You have to download also the "golden" firmware for SPEC card. It is used by
the drivers to recognize the hardware:
\begin{lstlisting}
$ wget http://www.ohwr.org/attachments/download/4057/spec-init.bin-2015-09-18
$ wget https://www.ohwr.org/project/spec-sw/uploads/636e7eaa2e1c3a884e2f9f694fdfd1b9/spec-init.bin-2015-09-18
$ sudo mv spec-init.bin-2015-09-18 /lib/firmware/fmc/spec-init.bin
\end{lstlisting}
......@@ -2044,7 +2050,7 @@ package.
First, please download the SDBFS image from \textit{ohwr.org}:
\begin{lstlisting}
$ wget http://www.ohwr.org/attachments/download/4060/sdbfs-flash.bin
$ wget https://www.ohwr.org/project/wr-cores/uploads/6f33b5a8660bd0f2ff7a07526b4484d6/sdbfs-flash.bin
\end{lstlisting}
It contains all the files required by the core. They are empty, but have to
exist in the SDBFS structure to be filled later from the WR PTP Core shell or
......@@ -2083,7 +2089,7 @@ This \textit{mcs} file already includes both SDBFS image and FPGA bitstream.
In the case when you want to run a custom gateware or you have a custom hardware, you can
download a standalone SDBFS image:
\begin{lstlisting}
$ wget http://www.ohwr.org/attachments/download/4558/sdbfs-standalone-160812.bin
$ wget https://www.ohwr.org/project/wr-cores/uploads/9dad995e74a3d49b472b8654833be01a/sdbfs-standalone-160812.bin
\end{lstlisting}
and generate a custom \textit{*.mcs} file with your own FPGA bitstream. You should
use the following layout:
......
......@@ -330,6 +330,11 @@ static int wrc_log_stats(void)
ptp_mode != WRC_MODE_SLAVE)
return 0;
last_jiffies = timer_get_tics();
/* Print only one time */
if(wrc_stat_running == -1)
wrc_stat_running = 0;
wrc_stats_last = s->update_count;
shw_pps_gen_get_time(&sec, &nsec);
......
......@@ -35,6 +35,9 @@ static int cmd_stat(const char *args[])
} else if (!strcasecmp(args[0], "off")) {
wrc_stat_running = 0;
pp_printf("statistics now off\n");
} else if (!strcasecmp(args[0], "1")) {
wrc_stat_running = -1; /* Special meaning... (only one) */
wrc_stats_last--; /* force a line to be printed */
} else
return -EINVAL;
return 0;
......
......@@ -18,12 +18,15 @@
the internal fabric. The frame, in the fabric, is prefixed with
a status word that includes the class bits.
The CPU is expected to receive PTP, ICMP, ARP and DHCP replies (so
local "bootpc" port).
The LM32 CPU is expected to receive PTP and if probably ICMP, ARP
and DHCP replies (so local "bootpc" port).
The fabric should receive Etherbone (i.e. UDP port 0xebd0), the
"streamer" protocol used by some CERN installation (ethtype 0xdbff)
and everything else if the "NIC pfilter" feature by 7Solutions is used.
"streamer" protocol used by some CERN installation (ethtype 0xdbff).
If an external NIC is used we should redirect everything (including
ARP,ICMP,DHCP) there excepting the PTP packets that should be handle
by LM32.
The logic cells connected to the fabric do their own check on the
frames, so it's not a problem if extra frames reach the fabric. Thus,
......@@ -413,9 +416,17 @@ void pfilter_init_novlan(char *fname)
pfilter_cmp(11, 0x0011, 0x00ff, MOV, FRAME_UDP);
pfilter_logic2(FRAME_UDP, FRAME_UDP, AND, FRAME_IP_OK);
#ifdef CONFIG_WR_NIC_CPU
/* For CPU: icmp unicast or ptp (or latency) */
/* Now, ARP & ICMP traffic are bypassed to the external fabric (NIC) */
pfilter_logic2(FRAME_FOR_CPU, FRAME_TYPE_PTP2, MOV, R_ZERO);
#else
/* For CPU: arp or icmp unicast or ptp (or latency) */
pfilter_logic2(FRAME_FOR_CPU, FRAME_TYPE_ARP, OR, FRAME_TYPE_PTP2);
pfilter_logic3(FRAME_FOR_CPU, FRAME_IP_OK, AND, FRAME_ICMP, OR, FRAME_FOR_CPU);
#endif
/* Now look in UDP ports: at offset 18 (14 + 20 + 8 = 36) */
pfilter_cmp(18, 0x0000, 0xff00, MOV, PORT_UDP_HOST); /* ports 0-255 */
......
......@@ -15,6 +15,10 @@
#include <hw/wb_uart.h>
#include <libdevmap.h>
#define VUART_EOL 13
#define VUART_CMD_USLEEP 1000000
#define VUART_CMD_PROMPT "wrc#"
static void wrpc_vuart_help(char *prog)
{
const char *mapping_help_str;
......@@ -80,6 +84,19 @@ static size_t wr_vuart_read(struct mapping_desc *vuart, char *buf, size_t size)
return n_rx;
}
/**
* It flush vuart buffer.
*
* @param[in] vuart token from dev_map()
*
*/
static void wr_vuart_flush(struct mapping_desc *vuart)
{
char rx;
while(wr_vuart_read(vuart,&rx,1) == 1) {}
}
/**
* It writes a number of bytes from a given buffer
* @param[in] vuart token from dev_map()
......@@ -99,16 +116,22 @@ static size_t wr_vuart_write(struct mapping_desc *vuart, char *buf, size_t size)
return size;
}
static void wrpc_vuart_term_main(struct mapping_desc *vuart, int keep_term)
static void wrpc_vuart_term_main(struct mapping_desc *vuart, int keep_term, int command_mode, char *command)
{
struct termios oldkey, newkey;
//above is place for old and new port settings for keyboard teletype
int need_exit = 0;
int cmd_sent = 0;
int cmd_len = 0;
char *prompt = VUART_CMD_PROMPT;
int i_prompt = 0;
int i;
fd_set fds;
int ret;
char rx, tx;
fprintf(stderr, "[press C-a to exit]\n");
if(!command_mode)
fprintf(stderr, "[press C-a to exit]\n");
if(!keep_term) {
tcgetattr(STDIN_FILENO,&oldkey);
......@@ -122,49 +145,102 @@ static void wrpc_vuart_term_main(struct mapping_desc *vuart, int keep_term)
tcsetattr(STDIN_FILENO,TCSANOW,&newkey);
}
while(!need_exit) {
struct timeval tv = {0, 10000};
FD_ZERO(&fds);
FD_SET(STDIN_FILENO, &fds);
/*
* Check if the STDIN has characters to read
* (what the user writes)
*/
ret = select(STDIN_FILENO + 1, &fds, NULL, NULL, &tv);
switch (ret) {
case -1:
perror("select");
break;
case 0: /* timeout */
break;
default:
if(!FD_ISSET(STDIN_FILENO, &fds))
if (!command_mode) {
struct timeval tv = {0, 10000};
FD_ZERO(&fds);
FD_SET(STDIN_FILENO, &fds);
/*
* Check if the STDIN has characters to read
* (what the user writes)
*/
ret = select(STDIN_FILENO + 1, &fds, NULL, NULL, &tv);
switch (ret) {
case -1:
perror("select");
break;
case 0: /* timeout */
break;
default:
if(!FD_ISSET(STDIN_FILENO, &fds))
break;
/* The user wrote something */
do {
ret = read(STDIN_FILENO, &tx, 1);
} while (ret < 0 && errno == EINTR);
if (ret != 1) {
fprintf(stderr, "nothing to read. Port disconnected?\n");
need_exit = 1; /* kill */
}
/* If the user character is C-a, then kill */
if(tx == '\x01')
need_exit = 1;
ret = wr_vuart_write(vuart, &tx, 1);
if (ret != 1) {
fprintf(stderr, "Unable to write (errno: %d)\n", errno);
need_exit = 1;
}
break;
/* The user wrote something */
do {
ret = read(STDIN_FILENO, &tx, 1);
} while (ret < 0 && errno == EINTR);
if (ret != 1) {
fprintf(stderr, "nothing to read. Port disconnected?\n");
need_exit = 1; /* kill */
}
/* If the user character is C-a, then kill */
if(tx == '\x01')
need_exit = 1;
ret = wr_vuart_write(vuart, &tx, 1);
if (ret != 1) {
fprintf(stderr, "Unable to write (errno: %d)\n", errno);
need_exit = 1;
} else {
if(!cmd_sent) {
/* Flush Vuart before sending command */
wr_vuart_flush(vuart);
/* Send command */
cmd_len = strlen(command);
ret = wr_vuart_write(vuart, command, cmd_len-1);
if (ret != cmd_len-1) {
fprintf(stderr, "Unable to write the command (errno: %d)\n",errno);
need_exit = 1;
}
/* Flush command echo */
wr_vuart_flush(vuart);
/* Send end character */
ret = wr_vuart_write(vuart, &command[cmd_len-1], 1);
if (ret != 1) {
fprintf(stderr, "Unable to write the end character of command (errno: %d)\n",errno);
need_exit = 1;
}
/* Wait for a while before reading command results */
usleep(VUART_CMD_USLEEP);
/* Discard characters until end of line control one */
while(wr_vuart_read(vuart, &rx, 1)) {
if(rx == VUART_EOL)
break;
}
cmd_sent = 1;
}
break;
}
/* Print all the incoming charactes */
while((wr_vuart_read(vuart, &rx, 1)) == 1)
fprintf(stderr,"%c", rx);
while((wr_vuart_read(vuart, &rx, 1)) == 1) {
if (command_mode == 1) {
/* Prompt detection, skip characters */
if (rx == prompt[i_prompt]) {
i_prompt++;
/* Prompt detected! */
if(i_prompt == strlen(prompt)) {
need_exit = 1;
break;
}
} else {
/* Check if some previous characters have been skipped by
prompt detector code and print them */
for(i = 0 ; i < i_prompt ; i++)
fprintf(stderr,"%c",prompt[i]);
/* Reset prompt detector */
i_prompt = 0;
/* Print current character */
fprintf(stderr,"%c", rx);
}
} else {
fprintf(stderr,"%c",rx);
}
}
}
if(!keep_term)
......@@ -176,6 +252,9 @@ int main(int argc, char *argv[])
{
char c;
int keep_term = 0;
int command_mode = 0;
char cmd[50];
int cmd_len = 0;
struct mapping_args *map_args;
struct mapping_desc *vuart = NULL;
......@@ -186,8 +265,18 @@ int main(int argc, char *argv[])
}
/* Parse specific args */
while ((c = getopt (argc, argv, "k")) != -1) {
while ((c = getopt (argc, argv, "c:k")) != -1) {
switch (c) {
case 'c':
/* Enable command mode */
command_mode = 1;
/* Get the command from args */
strcpy(cmd, optarg);
cmd_len = strlen(cmd);
/* Put end of buffer for terminal */
cmd[cmd_len] = VUART_EOL;
cmd[cmd_len+1] = 0;
break;
case 'k':
keep_term = 1;
break;
......@@ -206,7 +295,7 @@ int main(int argc, char *argv[])
goto out;
}
wrpc_vuart_term_main(vuart, keep_term);
wrpc_vuart_term_main(vuart, keep_term, command_mode, cmd);
dev_unmap(vuart);
return 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment