Commit d380b3d9 authored by Alessandro Rubini's avatar Alessandro Rubini

remove uart_sw, unused

This also include a ppsi commit. We must have both at the same time,
because each uses a feature of the other, to link sw-uart at build time.
Signed-off-by: Alessandro Rubini's avatarAlessandro Rubini <rubini@gnudd.com>
parent 60ace372
......@@ -5,7 +5,6 @@ mainmenu "WR PTP Core software configuration"
config WR_SWITCH
bool "Build rt_cpu.bin, for the WR-Switch FPGA"
default n
select UART
config WR_NODE
bool
......@@ -103,11 +102,6 @@ config PPSI
boolean
default y
config UART
boolean
default y if EMBEDDED_NODE
default n
config W1
depends on EMBEDDED_NODE
boolean
......@@ -424,25 +418,6 @@ config DETERMINISTIC_BINARY
If in doubt, say No.
config UART
boolean "Use hardware uart (and/or vuart if available)"
depends on (DEVELOPER && EMBEDDED_NODE) || WR_SWITCH
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 && EMBEDDED_NODE
default !UART
boolean "Use software uart"
help
The software uart is made up of two circular buffers. It can
be used either as an alternative to the harwdare UART or as
an addition. If the option is turned on, ppsi log messages
are routed to the software uart. The interactive wrpc shell
and diagnostics run on the hardware UART if available.
config NET_VERBOSE
depends on DEVELOPER && WR_NODE
boolean "Extra verbose messages for networking"
......
......@@ -139,8 +139,6 @@ ifneq ($(CONFIG_RAMSIZE),131072)
endif
endif
PPSI_USER_CFLAGS += -DDIAG_PUTS=uart_sw_write_string
PPSI-CFG-y = wrpc_defconfig
PPSI-CFG-$(CONFIG_P2P) = wrpc_pdelay_defconfig
PPSI-CFG-$(CONFIG_HOST_PROCESS) = unix_defconfig
......
......@@ -25,7 +25,6 @@ obj-$(CONFIG_W1) += dev/w1.o dev/w1-hw.o dev/w1-shell.o
obj-$(CONFIG_W1) += dev/w1-temp.o dev/w1-eeprom.o
obj-$(CONFIG_W1) += dev/temp-w1.o
obj-$(CONFIG_UART) += dev/uart.o
obj-$(CONFIG_UART_SW) += dev/uart-sw.o
obj-$(CONFIG_FAKE_TEMPERATURES) += dev/fake-temp.o
......
/*
* This work is part of the White Rabbit project
*
* Copyright (C) 2013 CERN (www.cern.ch)
* Author: Alessandro Rubini <rubini@gnudd.com>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#include <wrc.h>
#include <uart-sw.h>
static struct wrc_uart_sw __attribute__((aligned(16))) uart_sw_dev = {
.magic = UART_SW_MAGIC,
.wsize = CONFIG_UART_SW_WSIZE,
.rsize = CONFIG_UART_SW_RSIZE,
};
static uint16_t nreturned;
void uart_init_sw(void)
{
/* zero fields, as we may be reloaded */
uart_sw_dev.nwritten = uart_sw_dev.nread = 0;
}
void __attribute__((weak)) uart_init_hw(void)
{}
static void uart_sw_write_byte(int b)
{
int index;
if (b == '\n')
uart_sw_write_byte('\r');
index = uart_sw_dev.nwritten % CONFIG_UART_SW_WSIZE;
uart_sw_dev.wbuffer[index] = b;
uart_sw_dev.nwritten++;
/* fake a real uart, so user-space can poll not-too-fast */
usleep(1000 * 1000 / 11520);
}
int uart_sw_write_string(const char *s)
{
const char *t = s;
while (*s)
uart_sw_write_byte(*(s++));
return s - t;
}
static int uart_sw_read_byte(void)
{
int index;
if (nreturned == uart_sw_dev.nread) /* nread == written by host */
return -1;
index = (nreturned++) % CONFIG_UART_SW_RSIZE;
return uart_sw_dev.rbuffer[index];
}
/* alias the "hw" names to these, so this applies if !CONFIG_UART */
int puts(const char *s)
__attribute__((alias("uart_sw_write_string"), weak));
void uart_write_byte(int b)
__attribute__((alias("uart_sw_write_byte"), weak));
int uart_write_string(const char *s)
__attribute__((alias("uart_sw_write_string"), weak));
int uart_read_byte(void)
__attribute__((alias("uart_sw_read_byte"), weak));
......@@ -25,10 +25,6 @@ void uart_init_hw()
uart->BCR = CALC_BAUD(UART_BAUDRATE);
}
void __attribute__((weak)) uart_init_sw(void)
{}
void uart_write_byte(int b)
{
if (b == '\n')
......@@ -61,7 +57,3 @@ int uart_read_byte(void)
int puts(const char *s)
__attribute__((alias("uart_write_string")));
/* The next alias is for ppsi log messages, that go to sw_uart if built */
int uart_sw_write_string(const char *s)
__attribute__((alias("uart_write_string"), weak));
......@@ -73,10 +73,6 @@ void uart_init_hw(void)
}
void uart_init_sw(void)
{ printf("%s\n", __func__); }
void uart_exit(int i)
{
system("stty sane");
......
/*
* This work is part of the White Rabbit project
*
* Copyright (C) 2013 CERN (www.cern.ch)
* Author: Alessandro Rubini <rubini@gnudd.com>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#ifndef __UART_SW_H
#define __UART_SW_H
/* The host code (tools/wrpc-uart-sw) must include this too, for the struct */
#ifdef __lm32__
#include "uart.h" /* we need to offer the same prototypes */
#endif
/* These are currently static but can become Kconfig items */
#define CONFIG_UART_SW_WSIZE 256
#define CONFIG_UART_SW_RSIZE 32
#define UART_SW_MAGIC 0x752d7377 /* "u-sw" */
struct wrc_uart_sw {
uint32_t magic;
uint16_t wsize, nwritten;
uint16_t rsize, nread;
unsigned char wbuffer[CONFIG_UART_SW_WSIZE];
unsigned char rbuffer[CONFIG_UART_SW_RSIZE];
};
#endif /* __UART_SW_H */
......@@ -6,15 +6,10 @@
#ifndef __UART_H
#define __UART_H
void uart_init_sw(void);
void uart_init_hw(void);
void uart_write_byte(int b);
int uart_write_string(const char *s);
int puts(const char *s);
int uart_read_byte(void);
/* uart-sw is used by ppsi (but may be wrapped to normal uart) */
int uart_sw_write_string(const char *s);
#endif
ppsi @ 31c0e23b
Subproject commit 325a277479110cde0e99edfd62f7c99a778be21d
Subproject commit 31c0e23bed047439419c5c8e04a3da1da5ed0f3a
......@@ -3,7 +3,7 @@ SDBFS ?= no
CFLAGS = -Wall -ggdb -I../include
LDFLAGS = -lutil
ALL = genraminit genramvhd genrammif wrpc-uart-sw
ALL = genraminit genramvhd genrammif
ALL += wrpc-w1-read wrpc-w1-write
ALL += pfilter-builder
ALL += wrpc-dump mapper
......
/*
* This work is part of the White Rabbit project
*
* Copyright (C) 2013 CERN (www.cern.ch)
* Author: Alessandro Rubini <rubini@gnudd.com>
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <unistd.h>
#include <string.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <pty.h>
#include <arpa/inet.h> /* ntohl etc */
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/select.h>
#include "../include/uart-sw.h"
/*
* The following parameters match the spec, but can be changed on env/cmdline
*/
#define DEFAULT_BUS -1 /* all */
#define DEFAULT_BAR 0 /* first bar */
#define DEFAULT_RAMADDR 0 /* beginning */
#define DEFAULT_RAMSIZE 0x16000 /* 88k, default in spec */
#define MAX_DEVICES 8 /* no alloc, me lazy */
static struct usw_pci_id {
unsigned pci_v;
unsigned pci_d;
} spec_devices[] = {
{ 0x10dc /* CERN */, 0x018d /* SPEC */ },
{ 0x1a39 /* Gennum */, 0x0004 /* GN4124 */ },
{ 0, },
};
struct usw_device {
void *mapaddr;
int mapsize;
struct wrc_uart_sw *p;
uint16_t nreturned;
int fd;
};
static struct usw_device devs[MAX_DEVICES];
char *prgname;
/* Prepare communication according to user settings (currently pty only) */
static int usw_prepare_io(struct usw_device *dev)
{
char path[PATH_MAX];
int fdm, fds;
if (openpty(&fdm, &fds, path, NULL, NULL) < 0) {
fprintf(stderr, "%s: openpty(): %s\n", prgname,
strerror(errno));
return -1;
}
dev->fd = fdm;
close(fds);
printf("Opened \"%s\"; use screen or minicom\n", path);
return 0;
}
/* Open a uart-sw device, with an already-prepared mmap */
static int usw_open_device(char *name, struct usw_device *dev)
{
int i;
uint32_t *ptr;
for (i = 0; i < dev->mapsize; i += 16) {
ptr = dev->mapaddr + i;
if (*ptr == UART_SW_MAGIC)
break;
}
if (i == dev->mapsize) {
fprintf(stderr, "%s: no uart-sw in device %s\n", prgname,
name);
return -1;
}
fprintf(stderr, "%s: %s: found uart-sw at 0x%x\n", prgname, name, i);
dev->p = dev->mapaddr + i;
return usw_prepare_io(dev);
}
/* Access a PCI device, mmap and so on */
static int usw_access_pci(char *name, int index)
{
struct usw_device *dev = devs + index;
char path[PATH_MAX];
struct stat stbuf;
int fd;
memset(dev, 0, sizeof(*dev));
sprintf(path, "/sys/bus/pci/devices/%s/resource0", name);
if ((fd = open(path, O_RDWR | O_SYNC)) < 0) {
fprintf(stderr, "%s: %s: %s\n", prgname, path,
strerror(errno));
return -1;
}
fstat(fd, &stbuf);
dev->mapsize = stbuf.st_size;
dev->mapaddr = mmap(0, stbuf.st_size,
PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (dev->mapaddr == MAP_FAILED) {
fprintf(stderr, "%s: mmap(%s): %s\n", prgname, path,
strerror(errno));
return -1;
}
return usw_open_device(name, dev);
}
/* Scan PCI space for vendor and device; return number of successes */
static int usw_scan_pci(struct usw_pci_id *id, struct usw_device *arr,
int alen)
{
char path[PATH_MAX];
FILE *f;
struct dirent **namelist;
int i, j, n, ndevs;
unsigned v, d;
n = scandir("/sys/bus/pci/devices", &namelist, 0, 0);
if (n < 0) {
fprintf(stderr, "%s: /sys/bus/pci/devices: %s\n", prgname,
strerror(errno));
return -1;
}
for (i = ndevs = 0; i < n; i++) {
if (namelist[i]->d_name[0] == '.')
continue;
/* check vendor */
sprintf(path, "/sys/bus/pci/devices/%s/vendor",
namelist[i]->d_name);
f = fopen(path, "r");
if (!f) {
fprintf(stderr, "%s: %s: %s\n", prgname, path,
strerror(errno));
continue;
}
if (fscanf(f, "%i", &v) != 1)
continue;
fclose(f);
/* check device */
sprintf(path, "/sys/bus/pci/devices/%s/device",
namelist[i]->d_name);
f = fopen(path, "r");
if (!f) {
fprintf(stderr, "%s: %s: %s\n", prgname, path,
strerror(errno));
continue;
}
if (fscanf(f, "%i", &d) != 1)
continue;
fclose(f);
for (j = 0; id[j].pci_v; j++)
if (id[j].pci_v == v && id[j].pci_d == d)
break;
if (!spec_devices[j].pci_v)
continue; /* not found in whole array */
/* Ok, so this is ours. Celebrate, and open it */
fprintf(stderr, "%s: found device %04x:%04x: %s\n", prgname,
v, d, namelist[i]->d_name);
if (ndevs == alen) {
fprintf(stderr, "%s: array overflow, ignoring card\n",
prgname);
continue;
}
if (usw_access_pci(namelist[i]->d_name, ndevs))
continue;
ndevs++;
}
return ndevs;
}
/* Low-level shmem uart: output if outc >= 0; return -1 or input char */
static int usw_ll(struct usw_device *dev, int outc)
{
struct wrc_uart_sw local_uart;
uint32_t *ptr = (void *)&local_uart;
uint32_t *hwptr = (void *)dev->p;
int i, n, pos;
if (outc >= 0) {
/* FIXME: output */
}
/* The shmem is word-mapped but big-endian. So convert (inefficient) */
for (i = 0; i < sizeof(local_uart) / sizeof(*ptr); i++)
ptr[i] = ntohl(hwptr[i]);
if (outc >= 0) {
/* This is horrible, because of dual endian conversions */
n = ntohs(local_uart.nread) % CONFIG_UART_SW_RSIZE;
local_uart.rbuffer[n] = outc;
pos = (offsetof(struct wrc_uart_sw, rbuffer) + n) / 4;
hwptr[pos] = htonl(ptr[pos]);
local_uart.nread = htons(ntohs(local_uart.nread) + 1);
pos = offsetof(struct wrc_uart_sw, nread) / 4;
hwptr[pos] = htonl(ptr[pos]);
}
if (ntohs(local_uart.nwritten) < dev->nreturned)
dev->nreturned = 0; /* reloaded */
if (ntohs(local_uart.nwritten) > dev->nreturned) {
i = dev->nreturned % CONFIG_UART_SW_WSIZE;
i = local_uart.wbuffer[i];
dev->nreturned++;
return i;
}
return -1;
}
/* read/write the file descriptor, polling the low-level uart */
static int usw_do_io(struct usw_device *dev, int ready)
{
unsigned char buf[1]; /* oh so tiny */
int char_i, char_o;
char_o = -1;
if (ready) {
if (read(dev->fd, buf, 1) != 1)
/* error */;
char_o = buf[0];
}
while ((char_i = usw_ll(dev, char_o)) >= 0) {
buf[0] = char_i;
write(dev->fd, buf, 1);
char_o = -1;
}
return 0;
}
int main(int argc, char **argv)
{
int maxfd, ndev, i;
struct timeval tv = {0,};
fd_set set, fullset;
prgname = argv[0];
/* FIXME: parse commandline arguments */
ndev = usw_scan_pci(spec_devices, devs, MAX_DEVICES);
if (ndev < 1) {
fprintf(stderr, "%s: no suitable PCI devices\n", argv[0]);
exit(1);
}
FD_ZERO(&fullset);
maxfd = 0;
for (i = 0; i < ndev; i++) {
FD_SET(devs[i].fd, &fullset);
if (devs[i].fd > maxfd)
maxfd = devs[i].fd;
}
while (1) {
set = fullset;
tv.tv_usec = 50 * 1000;
i = select(maxfd + 1, &set, NULL, NULL, &tv);
if (i < 0)
continue;
for (i = 0; i < ndev; i++)
usw_do_io(devs + i, FD_ISSET(devs[i].fd, &set));
}
}
......@@ -49,7 +49,6 @@ static void wrc_initialize(void)
uint8_t mac_addr[6];
sdb_find_devices();
uart_init_sw();
uart_init_hw();
pp_printf("WR Core: starting up...\n");
......@@ -166,7 +165,6 @@ void init_hw_after_reset(void)
{
/* Ok, now init the devices so we can printf and delay */
sdb_find_devices();
uart_init_sw();
uart_init_hw();
timer_init(1);
}
......
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