Commit 5e4ed884 authored by Alessandro Rubini's avatar Alessandro Rubini

Merge branch 'host-support'

parents 529b4a4a c8675475
......@@ -64,6 +64,17 @@ config VLAN_FOR_CLASS6
default 100 if VLAN
default 0
config HOST_PROCESS
boolean
default n
config LM32
boolean
default !HOST_PROCESS
config EMBEDDED_NODE
boolean
default LM32 && WR_NODE
# CONFIG_WR_SWITCH has no further options at all at this point
......@@ -86,12 +97,12 @@ config PPSI
default y
config UART
depends on WR_NODE
boolean
default y
default y if EMBEDDED_NODE
default n
config W1
depends on WR_NODE
depends on EMBEDDED_NODE
boolean
default y
......@@ -164,8 +175,12 @@ config DEVELOPER
directly working on this package. Please don't use unless
you are a developer of wrpc-sw.
config RAMSIZE
config HOST_PROCESS
depends on DEVELOPER && WR_NODE
boolean "Build as a host process, to develop/debug network"
config RAMSIZE
depends on DEVELOPER && EMBEDDED_NODE
int "Size of the RAM in the FPGA for this program"
default 90112
help
......@@ -175,7 +190,7 @@ config RAMSIZE
choose your preferred value here.
config STACKSIZE
depends on DEVELOPER && WR_NODE
depends on DEVELOPER && EMBEDDED_NODE
int "Size of the stack area needed by this program"
default 2048
help
......@@ -197,7 +212,7 @@ config TEMP_POLL_INTERVAL
int "Poll interval, in seconds, for temperature sensors"
config CMD_LL
depends on DEVELOPER && WR_NODE
depends on DEVELOPER && EMBEDDED_NODE
bool "Build low-level commands for development/testing"
help
This enables low-level commands: "devmem" to read/write memory
......@@ -207,13 +222,13 @@ config CMD_LL
during the initial handshake
config FLASH_INIT
depends on WR_NODE && DEVELOPER
depends on DEVELOPER && EMBEDDED_NODE
default y
boolean "Read init commands from flash storage"
# CHECK_RESET for switch and node
config CHECK_RESET
depends on DEVELOPER
depends on DEVELOPER && !HOST_PROCESS
bool "Print a stack trace if reset happens"
help
If the CPU is following a NULL pointer, the program will
......@@ -222,7 +237,7 @@ config CHECK_RESET
then clears the stack (for next time) and restarts again.
config SPLL_FIFO_LOG
depends on DEVELOPER
depends on DEVELOPER && !HOST_PROCESS
bool "Add a circular buffer for spll logging, used by tools/wrpc-dump"
help
This option addrs 256 bytes to the wrpc bynary, to log
......@@ -273,7 +288,7 @@ config PPSI
Select this option for the ppsi engine (now only option)
config DETERMINISTIC_BINARY
depends on DEVELOPER && WR_NODE
depends on DEVELOPER && EMBEDDED_NODE
boolean "Build a binary that is the same every time"
help
This option is used to #ifdef __DATE__ and __TIME__ strings
......@@ -287,15 +302,14 @@ config DETERMINISTIC_BINARY
config UART
boolean "Use hardware uart (and/or vuart if available)"
depends on DEVELOPER && WR_NODE
default y
depends on DEVELOPER && EMBEDDED_NODE
help
This option selects the serial driver, connected to either
the USB socket, or "vuart" (software fifo) or both, according
to how the gateware is built.
config UART_SW
depends on DEVELOPER && WR_NODE
depends on DEVELOPER && EMBEDDED_NODE
default !UART
boolean "Use software uart"
help
......
# Tomasz Wlostowski for CERN, 2011,2012
-include $(CURDIR)/.config
CROSS_COMPILE ?= lm32-elf-
ifdef CONFIG_HOST_PROCESS
CROSS_COMPILE =
endif
export CROSS_COMPILE
CC = $(CROSS_COMPILE)gcc
......@@ -9,16 +15,16 @@ OBJDUMP = $(CROSS_COMPILE)objdump
OBJCOPY = $(CROSS_COMPILE)objcopy
SIZE = $(CROSS_COMPILE)size
-include $(CURDIR)/.config
AUTOCONF = $(CURDIR)/include/generated/autoconf.h
PPSI = ppsi
# we miss CONFIG_ARCH_LM32 as we have no other archs by now
obj-y = arch/lm32/crt0.o arch/lm32/irq.o
obj-$(CONFIG_LM32) = arch/lm32/crt0.o arch/lm32/irq.o
LDS-$(CONFIG_WR_NODE) = arch/lm32/ram.ld
LDS-$(CONFIG_WR_SWITCH) = arch/lm32/ram-wrs.ld
LDS-$(CONFIG_HOST_PROCESS) =
obj-$(CONFIG_WR_NODE) += wrc_main.o
obj-$(CONFIG_WR_SWITCH) += wrs_main.o
......@@ -30,14 +36,13 @@ obj-y += dump-info.o
$(CC) -include $(AUTOCONF) -E -P $*.ld.S -o $@
cflags-y = -ffreestanding -include $(AUTOCONF) -Iinclude/std -Iinclude \
cflags-y = -ffreestanding -include $(AUTOCONF) -Iinclude \
-I. -Isoftpll -Iipc
cflags-y += -I$(CURDIR)/pp_printf
cflags-$(CONFIG_LM32) += -Iinclude/std
cflags-$(CONFIG_PPSI) += \
-ffreestanding \
-include include/ppsi-wrappers.h \
-Iinclude \
-I$(PPSI)/arch-wrpc \
-I$(PPSI)/proto-ext-whiterabbit \
-Iboards/spec
......@@ -47,16 +52,16 @@ cflags-y += \
-I$(PPSI)/arch-wrpc/include \
-I$(PPSI)/include
obj-ppsi = \
$(PPSI)/ppsi.o
obj-ppsi = $(PPSI)/ppsi.o
obj-$(CONFIG_PPSI) += $(obj-ppsi)
obj-$(CONFIG_PPSI) += \
# Below, CONFIG_PPSI is wrong, as we can't build these for the host
obj-$(CONFIG_EMBEDDED_NODE) += \
monitor/monitor_ppsi.o \
lib/ppsi-wrappers.o \
$(obj-ppsi)
lib/ppsi-wrappers.o
CFLAGS_PLATFORM = -mmultiply-enabled -mbarrel-shift-enabled
LDFLAGS_PLATFORM = -mmultiply-enabled -mbarrel-shift-enabled \
cflags-$(CONFIG_LM32) += -mmultiply-enabled -mbarrel-shift-enabled
ldflags-$(CONFIG_LM32) = -mmultiply-enabled -mbarrel-shift-enabled \
-nostdlib -T $(LDS-y)
# packet-filter rules: for CONFIG_VLAN we use both sets
......@@ -71,13 +76,14 @@ include lib/lib.mk
include pp_printf/printf.mk
include dev/dev.mk
include softpll/softpll.mk
include host/host.mk
# ppsi already has div64 (the same one), so only pick it if not using ppsi.
ifndef CONFIG_PPSI
obj-y += pp_printf/div64.o
endif
# And always complain if we pick the libgcc division: 64/32 = 32 is enough here.
obj-y += check-error.o
obj-$(CONFIG_LM32) += check-error.o
# add system check functions like stack overflow and check reset
obj-y += system_checks.o
......@@ -86,13 +92,15 @@ obj-y += system_checks.o
obj-$(CONFIG_WR_NODE) += sdb-lib/libsdbfs.a
cflags-$(CONFIG_WR_NODE) += -Isdb-lib
CFLAGS = $(CFLAGS_PLATFORM) $(cflags-y) -Wall -Wstrict-prototypes \
CFLAGS = $(cflags-y) -Wall -Wstrict-prototypes \
-ffunction-sections -fdata-sections -Os -Wmissing-prototypes \
-include include/wrc.h -ggdb
LDFLAGS = $(LDFLAGS_PLATFORM) \
LDFLAGS = $(ldflags-y) \
-Wl,--gc-sections -Os -lgcc -lc
WRC-O-FLAGS-$(CONFIG_LM32) = --gc-sections -e _start
OBJS = $(obj-y)
OUTPUT-$(CONFIG_WR_NODE) = wrc
......@@ -116,10 +124,14 @@ endif
PPSI_USER_CFLAGS += -DDIAG_PUTS=uart_sw_write_string
PPSI-CFG-y = wrpc_defconfig
PPSI-CFG-$(CONFIG_HOST_PROCESS) = unix_defconfig
PPSI-FLAGS-$(CONFIG_LM32) = CONFIG_NO_PRINTF=y
$(obj-ppsi):
test -f $(PPSI)/.config || $(MAKE) -C $(PPSI) wrpc_defconfig
$(MAKE) -C $(PPSI) WRPCSW_ROOT=.. \
CROSS_COMPILE=$(CROSS_COMPILE) CONFIG_NO_PRINTF=y \
test -f $(PPSI)/.config || $(MAKE) -C $(PPSI) $(PPSI-CFG-y)
$(MAKE) -C $(PPSI) ppsi.o WRPCSW_ROOT=.. \
CROSS_COMPILE=$(CROSS_COMPILE) CONFIG_NO_PRINTF=y
USER_CFLAGS="$(PPSI_USER_CFLAGS)"
sdb-lib/libsdbfs.a:
......@@ -132,12 +144,15 @@ $(OUTPUT).elf: $(LDS-y) $(AUTOCONF) gitmodules $(OUTPUT).o config.o
$(SIZE) $@
$(OUTPUT).o: $(OBJS)
$(LD) --gc-sections -e _start -r $(OBJS) -T bigobj.lds -o $@
$(LD) $(WRC-O-FLAGS-y) -r $(OBJS) -T bigobj.lds -o $@
OBJCOPY-TARGET-$(CONFIG_LM32) = -O elf32-lm32 -B lm32
OBJCOPY-TARGET-$(CONFIG_HOST_PROCESS) = -O elf64-x86-64 -B i386
config.o: .config
sed '1,3d' .config > .config.bin
dd bs=1 count=1 if=/dev/zero 2> /dev/null >> .config.bin
$(OBJCOPY) -I binary -O elf32-lm32 -B lm32 \
$(OBJCOPY) -I binary $(OBJCOPY-TARGET-y) \
--rename-section .data=.data.config .config.bin $@
rm -f .config.bin
......
#
# Automatically generated make config: don't edit
#
# CONFIG_WR_SWITCH is not set
CONFIG_WR_NODE=y
CONFIG_PRINT_BUFSIZE=128
# CONFIG_PRINTF_XINT is not set
CONFIG_RAMSIZE=131072
CONFIG_PLL_VERBOSE=y
CONFIG_WRC_VERBOSE=y
CONFIG_HOST_PROCESS=y
# CONFIG_EMBEDDED_CODE is not set
# CONFIG_EMBEDDED_NODE is not set
# CONFIG_WR_NODE_PCS16 is not set
CONFIG_STACKSIZE=2048
CONFIG_PPSI=y
# CONFIG_UART is not set
CONFIG_IP=y
CONFIG_CMD_CONFIG=y
#
# wrpc-sw is tainted if you change the following options
#
CONFIG_DEVELOPER=y
CONFIG_PRINTF_FULL=y
# CONFIG_PRINTF_MINI is not set
# CONFIG_PRINTF_NONE is not set
CONFIG_NET_VERBOSE=y
CONFIG_SDB_STORAGE=y
# CONFIG_LEGACY_EEPROM is not set
CONFIG_VLAN_ARRAY_SIZE=1
obj-$(CONFIG_WR_NODE) += \
# Those hardware-specific files should not be built for the host, even if
# most of them give no error no warning. The host has different implementations
obj-$(CONFIG_EMBEDDED_NODE) += \
dev/endpoint.o \
dev/ep_pfilter.o \
dev/i2c.o \
dev/temperature.o \
dev/minic.o \
dev/pps_gen.o \
dev/syscon.o \
dev/sfp.o \
dev/devicelist.o \
dev/rxts_calibrator.o \
dev/flash.o
obj-$(CONFIG_WR_NODE) += \
dev/temperature.o \
dev/pps_gen.o
obj-$(CONFIG_WR_SWITCH) += dev/timer-wrs.o dev/ad9516.o
obj-$(CONFIG_LEGACY_EEPROM) += dev/eeprom.o
......@@ -30,7 +35,7 @@ obj-$(CONFIG_FAKE_TEMPERATURES) += dev/fake-temp.o
obj-y += $(pfilter-y:.bin=.o)
rules-%.o: rules-%.bin
$(OBJCOPY) -I binary -O elf32-lm32 -B lm32 $< $@
$(OBJCOPY) -I binary $(OBJCOPY-TARGET-y) $< $@
$(pfilter-y): tools/pfilter-builder
$^
......
......@@ -96,7 +96,8 @@ static uint64_t pps_get_utc(void)
return out;
}
void shw_pps_gen_get_time(uint64_t * seconds, uint32_t * nanoseconds)
void __attribute__((weak)) shw_pps_gen_get_time(uint64_t * seconds,
uint32_t * nanoseconds)
{
uint32_t ns_cnt;
uint64_t sec1, sec2;
......
......@@ -15,6 +15,7 @@
#include "types.h"
#include "i2c.h"
#include "onewire.h"
#include "endpoint.h"
#include <sdb.h>
#define SDBFS_BIG_ENDIAN
......@@ -297,6 +298,12 @@ int get_persistent_mac(uint8_t portnum, uint8_t * mac)
int i, class;
uint64_t rom;
if (IS_HOST_PROCESS) {
/* we don't have sdb working, so get the real eth address */
get_mac_addr(mac);
return 0;
}
if (sdbfs_open_id(&wrc_sdb, SDB_VENDOR, SDB_DEV_MAC) < 0)
return -1;
......
#include "flash.h"
void flash_init(void)
{}
int flash_write(uint32_t addr, uint8_t *buf, int count)
{ return 0; }
int flash_read(uint32_t addr, uint8_t *buf, int count)
{ return 0; }
int flash_erase(uint32_t addr, int count)
{ return 0; }
#include "syscon.h"
#include "spll_common.h"
#include "hw/etherbone-config.h"
static struct SYSCON_WB _syscon;
volatile struct SYSCON_WB *syscon = &_syscon;
static unsigned char _pps[sizeof(struct PPSG_WB)];
unsigned char *BASE_PPS_GEN = (void *)&_pps;
static unsigned char _pll[sizeof(struct SPLL_WB)];
unsigned char *BASE_SOFTPLL = (void *)&_pll;
static unsigned char _ebone[EB_IPV4 + 4];
unsigned char *BASE_ETHERBONE_CFG = (void *)&_ebone;
#include "i2c.h"
void mi2c_init(uint8_t i2cif)
{}
uint8_t mi2c_devprobe(uint8_t i2cif, uint8_t i2c_addr)
{ return 0; }
void mi2c_start(uint8_t i2cif)
{}
void mi2c_repeat_start(uint8_t i2cif)
{}
void mi2c_stop(uint8_t i2cif)
{}
unsigned char mi2c_put_byte(uint8_t i2cif, unsigned char data)
{ return 1; }
void mi2c_get_byte(uint8_t i2cif, unsigned char *data, uint8_t last)
{ *data = 0; }
#include <stdio.h>
#include <w1.h>
struct w1_bus wrpc_w1_bus;
void wrpc_w1_init(void)
{ printf("%s\n", __func__); }
int w1_scan_bus(struct w1_bus *bus)
{ printf("%s\n", __func__); return 0; }
int w1_read_eeprom_bus(struct w1_bus *bus,
int offset, uint8_t *buffer, int blen)
{ return -1; }
int w1_write_eeprom_bus(struct w1_bus *bus,
int offset, const uint8_t *buffer, int blen)
{ return -1; }
int w1_erase_eeprom_bus(struct w1_bus *bus, int offset, int blen)
{ return -1; }
void uart_exit(int i);
obj-$(CONFIG_HOST_PROCESS) += \
host/misc.o \
host/fake-i2c.o \
host/fake-w1.o \
host/fake-flash.o \
host/fake-hw.o \
host/ptp.o \
host/socket.o
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <time.h>
#include <termios.h>
#include <sys/select.h>
#include <sys/time.h>
#include "irq.h"
#include "uart.h"
#include "endpoint.h"
#include "pps_gen.h"
#include "rxts_calibrator.h"
#include "host.h"
uint32_t _endram;
int wrc_stat_running;
/* timer */
void usleep_init(void)
{ printf("%s\n", __func__); }
void timer_init(uint32_t enable)
{ printf("%s\n", __func__); }
void timer_delay(uint32_t tics)
{
usleep(tics * 1000);
}
uint32_t uptime_sec;
uint32_t timer_get_tics(void)
{
struct timeval tv;
uint64_t msecs;
gettimeofday(&tv, NULL);
msecs = tv.tv_sec * 1000 + tv.tv_usec / 1000;
return msecs;
}
void shw_pps_gen_get_time(uint64_t * seconds, uint32_t * nanoseconds)
{
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
if (seconds)
*seconds = ts.tv_sec;
if (nanoseconds)
*nanoseconds = ts.tv_nsec / NS_PER_CLOCK;
}
/* uart */
void uart_init_hw(void)
{
struct termios t;
printf("%s\n", __func__);
tcgetattr(STDIN_FILENO, &t);
cfmakeraw(&t);
t.c_oflag |= ONLCR | OPOST;
tcsetattr(STDIN_FILENO, 0, &t);
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stdin, NULL, _IONBF, 0);
printf("UART simulator on the host: use ctrl-C or ctrl-D to exit\n");
}
void uart_init_sw(void)
{ printf("%s\n", __func__); }
void uart_exit(int i)
{
system("stty sane");
exit(i);
}
int uart_read_byte(void)
{
fd_set set;
int ret = -1;
struct timeval tv = {0, 0};
FD_ZERO(&set);
FD_SET(STDIN_FILENO, & set);
if (select(STDIN_FILENO + 1, &set, NULL, NULL, &tv) > 0)
ret = getchar();
/* Use ctrl-C and ctrl-D specially (hack!) */
if (ret == 3 || ret == 4) {
uart_exit(0);
}
return ret;
}
/* unused stuff */
void disable_irq(void)
{ printf("%s\n", __func__); }
void enable_irq(void)
{ printf("%s\n", __func__); }
int wrc_mon_gui(void)
{ printf("%s\n", __func__); return 0;}
int wrc_log_stats(void)
{
static uint32_t last_jiffies;
if (!wrc_stat_running)
return 0;
if (!last_jiffies)
last_jiffies = timer_get_tics() - 1 - wrc_ui_refperiod;
if (time_before(timer_get_tics(), last_jiffies + wrc_ui_refperiod))
return 0;
last_jiffies = timer_get_tics();
printf("%s\n", __func__);
return 1;
}
void sdb_find_devices(void)
{ printf("%s\n", __func__); }
int calib_t24p(int mode, uint32_t *value)
{ return 0; }
int ep_get_bitslide(void)
{ return 0; }
int ep_enable(int enabled, int autoneg)
{ return 0; }
void ep_init(uint8_t mac_addr[])
{ printf("%s\n", __func__); }
void pfilter_init_default(void)
{}
#include "wrc_ptp.h"
int wrc_ptp_init(void)
{ return 0; }
int wrc_ptp_set_mode(int mode)
{ return 0; }
int wrc_ptp_get_mode(void)
{ return 0; }
int wrc_ptp_start(void)
{ return 0; }
int wrc_ptp_stop(void)
{ return 0; }
int wrc_ptp_update(void)
{ return 0; }
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <net/if_arp.h>
#include "include/types.h" /* with "types.h" I might get the standard one... */
#include "endpoint.h"
#include "ptpd_netif.h"
#include "minic.h"
#include "hw/pps_gen_regs.h"
#include "host.h"
static int dumpstruct(FILE *dest, char *name, void *ptr, int size)
{
int ret, i;
unsigned char *p = ptr;
if (!NET_IS_VERBOSE)
return 0;
ret = fprintf(dest, "dump %s at %p (size 0x%x)\n", name, ptr, size);
for (i = 0; i < size; ) {
ret += fprintf(dest, "%02x", p[i]);
i++;
ret += fprintf(dest, i & 3 ? " " : i & 0xf ? " " : "\n");
}
if (i & 0xf)
ret += fprintf(dest, "\n");
return ret;
}
static char ifname[16];
static char ethaddr[ETH_ALEN];
static int ethaddr_ok;
int sock;
void minic_init(void)
{
char *name = getenv("WRPC_MINIC");
struct ifreq ifr;
struct packet_mreq req;
struct sockaddr_ll addr;
int ethindex;
if (!name)
name = "eth0";
strcpy(ifname, name);
printf("%s: using %s as interface\n", __func__, ifname);
sock = socket(PF_PACKET, SOCK_RAW | SOCK_NONBLOCK, ETH_P_1588);
if (sock < 0) {
printf("%s: can`t open raw socket: %s\n",
__func__, strerror(errno));
}
memset(&ifr, 0, sizeof(ifr));
strcpy(ifr.ifr_name, ifname);
if (ioctl(sock, SIOCGIFHWADDR, &ifr) < 0) {
printf("%s: can`t get hw address of \"%s\": %s\n",
__func__, ifname, strerror(errno));
}
memcpy(ethaddr, &ifr.ifr_ifru.ifru_hwaddr.sa_data, ETH_ALEN);
ethaddr_ok = 1;
strcpy(ifr.ifr_name, ifname);
if (ioctl(sock, SIOCGIFINDEX, &ifr) < 0) {
printf("%s: can`t get index of \"%s\": %s\n",
__func__, ifname, strerror(errno));
}
ethindex = ifr.ifr_ifindex;
memset(&req, 0, sizeof(req));
req.mr_ifindex = ethindex;
req.mr_type = PACKET_MR_PROMISC;
if (setsockopt(sock, SOL_PACKET, PACKET_ADD_MEMBERSHIP,
&req, sizeof(req)) < 0) {
printf("%s: can`t set \"%s\" to promiscuous mode: %s\n",
__func__, ifname, strerror(errno));
}
addr.sll_family = AF_PACKET;
addr.sll_protocol = htons(ETH_P_ALL);
addr.sll_ifindex = ifr.ifr_ifindex;
if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
fprintf(stderr, "%s: can't bind to \"%s\": %s\n",
__func__, ifname, strerror(errno));
}
/* Finally, put the current date into the SEC counter of ppsg */
{
uint64_t utc = time(NULL);
uint32_t *ptr;
ptr = (void *)BASE_PPS_GEN
+ offsetof(struct PPSG_WB, CNTR_UTCLO);
*ptr = utc;
ptr = (void *)BASE_PPS_GEN
+ offsetof(struct PPSG_WB, CNTR_UTCHI);
*ptr = utc >> 32;
}
}
/* We have a problem: this is called before minic_init(), so we dup code */
void get_mac_addr(uint8_t dev_addr[])
{
char *name = getenv("WRPC_MINIC");
struct ifreq ifr;
int sock;
if (ethaddr_ok) {
memcpy(dev_addr, ethaddr, ETH_ALEN);
return;
}
if (!name)
name = "eth0";
sock = socket(PF_PACKET, SOCK_RAW | SOCK_NONBLOCK, ETH_P_1588);
memset(&ifr, 0, sizeof(ifr));
strcpy(ifr.ifr_name, name);
ioctl(sock, SIOCGIFHWADDR, &ifr);
memcpy(dev_addr, &ifr.ifr_ifru.ifru_hwaddr.sa_data, ETH_ALEN);
close(sock);
}
void set_mac_addr(uint8_t dev_addr[])
{
printf("%s: no implemented yet\n", __func__);
}
int minic_rx_frame(struct wr_ethhdr *hdr, uint8_t * payload, uint32_t buf_size,
struct hw_timestamp *hwts)
{
unsigned char frame[1500];
int ret;
ret = recv(sock, frame, sizeof(frame), MSG_DONTWAIT);
if (ret < 0 && errno == EAGAIN)
return 0;