Commit 42b59610 authored by Alessandro Rubini's avatar Alessandro Rubini

Merge branch 'hwinfo-sdb'

parents 3a2e2679 b454142c
......@@ -41,7 +41,6 @@ fake_flasher()
showhelp()
{
printf "Usage: $0 [options] [<firmware>.tar] [DEV]\n\n"
printf "MAC:\t MAC address in hexadecimal seperated by ':' (i.e, AB:CD:EF:01:23:45)\n"
printf "<firmware>.tar: Use the file in the firmware to flash the device\n"
printf "DEV:\t The usb device (by default it is /dev/ttyACM0)\n"
printf "Options: \n"
......@@ -50,8 +49,6 @@ showhelp()
printf " -g|--gateware\t Select the gateware: 18p (18 ports, default), 8p (8 ports)\n"
printf " -e \t\t Completely erase the memory (Can erase your configuration)\n"
printf " -b|--build\t Use files that you have built in the WRS_OUTPUT_DIR\n"
printf " -m1|--mac1\t Default MAC address for the ethernet port on board\n"
printf " -m2|--mac2\t Default base MAC address for the switch ports\n"
exit 0
}
......@@ -68,34 +65,6 @@ checkExit()
fi
}
checkMAC()
{
X="[0-9a-fA-F][0-9a-fA-F]"
if echo $1 | grep "^[0-9a-fA-F][02468aceACE]:${X}:${X}:${X}:${X}:${X}\$" > /dev/null; then
return 0
fi
return 1
}
modifyMAC()
{
origin=$1
new=$2
cp $origin $new
echo "Configure the MAC addresses:"
echo " MAC1 $MAC1"
echo " MAC2 $MAC2"
# MAC address doesn't need any modification
if [ $silent ]; then
return 1;
fi
# Modify MAC address
sed -i "s/$MAC1_DEF/$MAC1/" $new
sed -i "s/$MAC2_DEF/$MAC2/" $new
return 0
}
# Go to the top directory
dir=$(dirname $0)/..
WRS_BASE_DIR=$(cd $dir && /bin/pwd)
......@@ -202,22 +171,8 @@ while [ $# -ge 1 ]; do
/* ) DEV="-s $1"; shift ;;
-m1|--mac1)
MAC1="$2"
checkMAC $MAC1
if [ $? -eq 1 ];then
echo "Error: MAC address 1 invalid ($MAC1)"
exit 1
fi
shift; shift;;
-m2|--mac2)
MAC2="$2"
checkMAC $MAC2
if [ $? -eq 1 ];then
echo "Error: MAC address 2 invalid ($MAC2)"
exit 1
fi
-m1|--mac1|-m2|--mac2)
echo "Error: can't change mac1 and mac2 any more. See docs" >& 2
shift; shift;;
-[ecs])
......@@ -310,14 +265,9 @@ fi
echo -n " please release the flash button and press Enter to start flashing: "
read unused
# Create a temporary barebox binary with modified MAC addresses
Tbarebox=$WRSTMPDIR/bb.new
modifyMAC ${barebox} ${Tbarebox}
## Flashing DataFlash: at91bootstrap at 0, then barebox at 0x8400 (33792)
if $df; then
${FLASHER} -m df $FLAGS $DEV ${at91bs} 0 ${Tbarebox} 33792
${FLASHER} -m df $FLAGS $DEV ${at91bs} 0 ${barebox} 33792
fi
## Prepare for the NAND flashing procedure (kernel, initramfs, /usr)
......@@ -337,7 +287,7 @@ if $nf; then
# Start nand flashing procedure
$FLASHER -m ddr $FLAGS $DEV \
${Tbarebox} 0x0000000 \
${barebox} 0x0000000 \
${kernel} 0x1000000 \
${MAGICSTR} 0x17FFFF8 \
${initramfs} 0x1800000
......@@ -364,7 +314,7 @@ if $ddr; then
# barebox would be enough, but place kernel and initramfs too. it costs nothing
$FLASHER -m ddr $FLAGS $DEV \
${Tbarebox} 0x0000000 \
${barebox} 0x0000000 \
${kernel} 0x1000000 \
${initramfs} 0x1800000
......
#!/bin/bash
# This program, that should only be used by the manufacturer,
# creates and SDB image file, to be written in dataflash:
# (/dev/mtd5 in the switch).
#
# 0x000000094800-0x000000095040 : "hwinfo"
#
# The sdb file has a predefined structure, and we are not expected to
# change the manufacturer name. We chose to have it "hardwired", in a
# way, to avoid building gensdbfs during switch installation, as it's
# an extra burden and an extra dependency. We rather use sed for mac
# addresses (like we always did) and we write hwinfo in place, at
# offset 0x420.
# See hwinfo-sdb/--SDB-CONFIG-- and the respective
# commit for details.
dir=$(dirname $0)/..
WRS_BASE_DIR=$(cd $dir && /bin/pwd)
SDB_TMP=$(mktemp /tmp/wrs-hwinfo.XXXXXX)
XTRA_TMP=$(mktemp /tmp/wrs-hwinfo.xtra.XXXXXX)
cp $WRS_BASE_DIR/binaries/sdb-for-dataflash $SDB_TMP
# Some of what follows comes from ./flash-wrs, where we used to do the same
# Default MAC address for the switch board ethernet
MAC1_DEF="02:34:56:78:9A:BC"
MAC1=$MAC1_DEF
# Default base MAC address for the 18 switch ports
MAC2_DEF="02:34:56:78:9A:00"
MAC2=$MAC2_DEF
checkMAC()
{
X="[0-9a-fA-F][0-9a-fA-F]"
if echo $1 | grep "^[0-9a-fA-F][02468aceACE]:${X}:${X}:${X}:${X}:${X}\$" > /dev/null; then
return 0
fi
return 1
}
noversion=true
# parse arguments and modify the temporary copy of the sdb image
while [ $# -ge 1 ]; do
case $1 in
-m1|--mac1|--eth0.ethaddr)
MAC1="$2"
checkMAC $MAC1
if [ $? -eq 1 ];then
echo "Error: MAC address 1 invalid ($MAC1)"
exit 1
fi
sed -i "s/$MAC1_DEF/$MAC1/" $SDB_TMP
shift; shift
;;
-m2|--mac2|--wr0.ethaddr)
MAC2="$2"
checkMAC $MAC2
if [ $? -eq 1 ];then
echo "Error: MAC address 2 invalid ($MAC2)"
exit 1
fi
sed -i "s/$MAC2_DEF/$MAC2/" $SDB_TMP
shift; shift
;;
-v|--version)
V="$2"
if echo $V | grep -v -q '^[0-9]\.[0-9]$'; then
echo "Version must be <digit>.<digit>, not \"$V\"" >& 2
exit 1;
fi
noversion=false
sed -i "s/000/$V/" $SDB_TMP
shift; shift
;;
# all other information goes in the "extra" file
-n|--scb_sn)
echo "scb_serial: $2" >> $XTRA_TMP
shift; shift
;;
-b|--scb_batch)
echo "scb_batch: $2" >> $XTRA_TMP
shift; shift
;;
-f|--fpga)
echo "fpga_type: $2" >> $XTRA_TMP
shift; shift
;;
-x|--extra)
# this argument is expected to be tagged format
echo "$2" >> $XTRA_TMP
shift; shift
;;
-F|--file)
# and the file is expected to be tagged format too
cat "$2" >> $XTRA_TMP
shift; shift
;;
*)
echo "Unknown argument \"$1\"; please see sources/docs" >& 2
exit 1
;;
esac
done
if $noversion; then
echo "You must specify the SCB version (e.g. \"-v 3.3\")" >& 2
exit 1
fi
# Finally, replace the XTRA part (second half)
# But dd is crappy, it prints statistics to stderr, we don't want them
dd conv=notrunc if=$XTRA_TMP of=$SDB_TMP bs=1056 seek=1 2> /dev/null
if [ $? -ne 0 ]; then
# do it again, so we see the errors
dd conv=notrunc if=$XTRA_TMP of=$SDB_TMP bs=1056 seek=1
exit 1
fi
rm $XXTRA_TMP
# echo the name, to be used by the manufacturer build procedure.
echo $SDB_TMP
......@@ -630,7 +630,7 @@ approach like the global PPSi values described in @ref{wrsPpsi}.
The implementation is easier, because I rely on the fact that versions
never change while the process runs. So I retrieve the version strings
at initialization time, by calling ``@t{wrsw_version -t}'' (tagged)
at initialization time, by calling ``@t{wrs_version -t}'' (tagged)
and parsing its @i{stdout}. Parsing is easier than what we have in
@i{wrsPpsi}, but my plan is having a unified parser overall, and eventually
get rid of this simplified special case.
......
......@@ -366,7 +366,7 @@ All these tools are found in `/wr/bin/` which is included in the `$PATH`.
The following list resumes the most interesting commands:
* `wrsw_version`: Print information about the SW & HW version of the [WRS].
* `wrs_version`: Print information about the SW & HW version of the [WRS].
* `rtu_stat`: Routing Table Unit Statistic, returns the routing table information where we can find which MAC needs to be forwarded to which port. It also allows to add and delete entries.
* `wr_mon`: WR Switch Sync Monitor, outputs information about the state of WR syncrhonisation such as Phase Tracking, Master-Slave delay, link asymmetry, etc...
* `spll_dbg_proxy`: SoftPLL debug proxy, reads out the debug FIFO datastream from the SoftPLL and proxies it via TCP connection to the application running on an outside host, where it can be plotted, analyzed, etc.
......@@ -686,7 +686,7 @@ executing the following command:
~~~~~{.bash}
#On the WRS
wrsw_version > /tmp/bug_report.txt
wrs_version > /tmp/bug_report.txt
rtu_stat >> /tmp/bug_report.txt
dmesg >> /tmp/bug_report.txt
......
This diff is collapsed.
......@@ -135,12 +135,6 @@ the up-arrow will show interference between shells).
@itemize @bullet
@item We need to save some hardware information items to @i{dataflash}.
Such information should never be modified after the switch is shipped.
The plan is using SDB for it (i.e. SDBFS) but we must define proper
procedures and prevent accidental erasure of such data. This is urgent,
and we need it by September for release 4.1.
@item Installation and run-time boots in two different ways. At installation
we do everything using the @i{sam-ba} tools, while runtime relies on
@i{at91boot}. This means we are currently maintaining two different
......@@ -274,14 +268,6 @@ all configurations to the PPSi config file -- the delays and all the rest
are PTP-specific anyways, and PPSi supports per-architecture configuration
items.
@item We need a way to change parameters at run time in the @i{softpll}
implementation running on the switch. We may base this on the @i{ipc}
mechanism that is already in place, or design a well-know structure in
the LM32 code, so the main CPU can just change parameters on the fly.
I prefer the latter approach, but I need to talk with LM32 developers
to agree about how to do that, and ensure everybody follows the policy
we define.
@end itemize
@c ##########################################################################
......@@ -355,14 +341,6 @@ GrandMaster.
@itemize @bullet
@item Tool naming is completely inconsistent. We should move everything
to use unambiguous naming: @t{wr_} for every wr-wide item, and @t{wrsw_}
for every switch-specific thing. (Actually, @t{wrs_} would be better,
as it doesn't look like ``software'' and we use wrs/wrn internally already,
but several tools use @t{wrsw_} as a prefix already.
We fixed the ``shower'' name -- (@t{shw_ver}: switch hardware version),
but more are there. (@b{Update}: Greg says to use @t{wrs_} and do it soon).
@item A number of tools @t{mmap()} FPGA memory, but there is no
locking so it is (remotely) possible for tools to interfere and get
wrong results. We should define a good policy with proper locking, to
......
# We have 5 files only: eth0.ethaddr, wr0.ethaddr, manufacturer, scb_version
# and hw_info.
#
# They are at static addresses so to be able to change them from a script
# without re-running "gensdbfs", even if currently we change in-place with
# sed by forcing the size of the file to remain unchanged.
#
# The directory, at offset 0, takes 64 * (5 + 1) = 0x140: reserve
# 0x200 to be safe
.
position = 0
eth0.ethaddr
position = 0x200
wr0.ethaddr
position = 0x220
scb_version
position = 0x240
manufacturer
position = 0x260
# this is a tagged text file, using a whole dataflash page, at a page offset
# the offset and size amount to one page of the old device, 4 pages of the new.
# in the end, we reserve 0x840 bytes for this hwinfo.
hw_info
position = 0x420
maxsize = 0x420
02:34:56:78:9A:BC
\ No newline at end of file
02:34:56:78:9A:00
From 2a346543d6cb16c4e7e638641cc947c73fb43068 Mon Sep 17 00:00:00 2001
From: Alessandro Rubini <rubini@gnudd.com>
Date: Mon, 15 Sep 2014 11:40:01 +0200
Subject: [PATCH 12/14] lib/sdb: bb fixes (to be ported in fpga-config-space)
Signed-off-by: Alessandro Rubini <rubini@gnudd.com>
---
lib/sdb/libsdbfs-kernel.h | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/lib/sdb/libsdbfs-kernel.h b/lib/sdb/libsdbfs-kernel.h
index 16e359e..a121d0e 100644
--- a/lib/sdb/libsdbfs-kernel.h
+++ b/lib/sdb/libsdbfs-kernel.h
@@ -1,7 +1,11 @@
#include <linux/types.h>
#include <linux/string.h>
-#include <linux/errno.h>
+#ifdef __BAREBOX__
+# include <errno.h>
+#else /* really linux */
+# include <linux/errno.h>
+#endif
#include <asm/byteorder.h>
/*
@@ -13,7 +17,9 @@
* is not installed in /usr/include/linux/types.h, so use it to check.
*/
#ifndef DECLARE_BITMAP
-# error "Please point LINUX to a source tree if you define __KERNEL__"
+# ifndef __BAREBOX__ /* Barebox looks like the kernel and misses the define */
+# error "Please point LINUX to a source tree if you define __KERNEL__"
+# endif
#endif
#define SDB_KERNEL 1
--
1.7.10.4
From 55893c8ebab97be71eacc2f4814a2b41616ec7c1 Mon Sep 17 00:00:00 2001
From: Alessandro Rubini <rubini@gnudd.com>
Date: Mon, 15 Sep 2014 11:40:34 +0200
Subject: [PATCH 12/13] libsdb: integrate in build system
Signed-off-by: Alessandro Rubini <rubini@gnudd.com>
---
lib/Kconfig | 3 +++
lib/Makefile | 1 +
lib/sdb/Makefile | 44 +-------------------------------------------
3 files changed, 5 insertions(+), 43 deletions(-)
diff --git a/lib/Kconfig b/lib/Kconfig
index d9ad4aa..7a2884e 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -47,6 +47,9 @@ config LIBUBIGEN
config LIBMTD
bool
+config LIBSDB
+ bool
+
config STMP_DEVICE
bool
diff --git a/lib/Makefile b/lib/Makefile
index e8769a9..d4295fe 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -44,3 +44,4 @@ obj-y += gui/
obj-$(CONFIG_XYMODEM) += xymodem.o
obj-y += unlink-recursive.o
obj-$(CONFIG_STMP_DEVICE) += stmp-device.o
+obj-$(CONFIG_LIBSDB) += sdb/
diff --git a/lib/sdb/Makefile b/lib/sdb/Makefile
index 4699673..d3f06a4 100644
--- a/lib/sdb/Makefile
+++ b/lib/sdb/Makefile
@@ -1,43 +1 @@
-
-LINUX ?= /lib/modules/$(shell uname -r)/build
-
-# If we compile for the kernel, we need to include real kernel headers.
-# The thing is enough a mess that I moved it to a different file
-include Makefile.arch
-
-
-AS = $(CROSS_COMPILE)as
-LD = $(CROSS_COMPILE)ld
-CC = $(CROSS_COMPILE)gcc
-CPP = $(CC) -E
-AR = $(CROSS_COMPILE)ar
-NM = $(CROSS_COMPILE)nm
-STRIP = $(CROSS_COMPILE)strip
-OBJCOPY = $(CROSS_COMPILE)objcopy
-OBJDUMP = $(CROSS_COMPILE)objdump
-
-# calculate endianness at compile time
-ENDIAN := $(shell ./check-endian $(CC))
-
-CFLAGS = -Wall -ggdb -O2
-CFLAGS += -I../include/linux -I../include # for <sdb.h>
-CFLAGS += -ffunction-sections -fdata-sections
-CFLAGS += -Wno-pointer-sign
-CFLAGS += $(ENDIAN) $(LINUXINCLUDE)
-
-
-LIB = libsdbfs.a
-OBJS = glue.o access.o
-
-all: $(LIB)
-
-$(OBJS): $(wildcard *.h)
-
-$(LIB): $(OBJS)
- $(AR) r $@ $(OBJS)
-
-clean:
- rm -f $(OBJS) $(LIB) *~ core
-
-# add the other unused targets, so the rule in ../Makefile works
-modules install modules_install:
+obj-y += glue.o access.o
--
1.7.10.4
From e5312e4e8b58dfe5480b6bd3e22470527cfb85f7 Mon Sep 17 00:00:00 2001
From: Alessandro Rubini <rubini@gnudd.com>
Date: Mon, 15 Sep 2014 11:40:59 +0200
Subject: [PATCH 13/13] commands: add sdb commands to list, read, setvar
Signed-off-by: Alessandro Rubini <rubini@gnudd.com>
---
commands/Kconfig | 7 ++
commands/Makefile | 1 +
commands/sdb.c | 192 +++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 200 insertions(+)
create mode 100644 commands/sdb.c
diff --git a/commands/Kconfig b/commands/Kconfig
index 352e8bf..89cadec 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -756,6 +756,13 @@ config CMD_DETECT
actual probe of the client devices until they are needed. Use the
'detect' command on the physical device to trigger probing.
+config CMD_SDB
+ bool
+ select LIBSDB
+ prompt "commands for reading SDB information"
+ help
+ This enables "sdbinfo", "sdbset" and "sdbread".
+
menuconfig CMD_WD
bool
depends on WATCHDOG
diff --git a/commands/Makefile b/commands/Makefile
index 91ec0e9..e97291e 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -91,6 +91,7 @@ obj-$(CONFIG_CMD_FILETYPE) += filetype.o
obj-$(CONFIG_CMD_BAREBOX_UPDATE)+= barebox-update.o
obj-$(CONFIG_CMD_MIITOOL) += miitool.o
obj-$(CONFIG_CMD_DETECT) += detect.o
+obj-$(CONFIG_CMD_SDB) += sdb.o
obj-$(CONFIG_CMD_BOOT) += boot.o
obj-$(CONFIG_CMD_DEVINFO) += devinfo.o
obj-$(CONFIG_CMD_READF) += readf.o
diff --git a/commands/sdb.c b/commands/sdb.c
new file mode 100644
index 0000000..e0cd5a4
--- /dev/null
+++ b/commands/sdb.c
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2014 CERN.
+ * Author: Alessandro Rubini for BE-CO-HT (White Rabbit project)
+ *
+ * Please use according to GNU GPL 2 or later
+ */
+#include <common.h>
+#include <command.h>
+#include <init.h>
+#include <malloc.h>
+#include <errno.h>
+#include <fs.h>
+#include <fcntl.h>
+#include <xfuncs.h>
+#include <getopt.h>
+#include <environment.h>
+
+#include <../lib/sdb/libsdbfs.h> /* hackish */
+
+#define BUFSIZE 1024 /* like cat.c in this directory */
+
+/* This is the drvdata in the SDB information */
+struct bb_sdb_drvdata {
+ int fd;
+};
+
+static struct bb_sdb_drvdata drvdata;
+
+/* and how to read the thing: use straight barebox POSIX interface */
+static int bb_sdb_read(struct sdbfs *fs, int offset, void *buf, int count)
+{
+ struct bb_sdb_drvdata *dd = fs->drvdata;
+ int fd = dd->fd;
+
+ if (lseek(fd, offset, SEEK_SET) < 0)
+ return -1;
+ return read(fd, buf, count);
+}
+
+static struct sdbfs bb_sdb_instance = {
+ .drvdata = &drvdata,
+ .entrypoint = 0, /* unfortunately: to be fixed */
+ .read = bb_sdb_read,
+};
+
+/* The subcommands, assuming the device is opened and closed by the caller */
+static int bb_sdb_ls(void)
+{
+ struct sdb_device *d;
+ struct sdb_product *p;
+ struct sdb_component *c;
+ int new = 1;
+
+ while ( (d = sdbfs_scan(&bb_sdb_instance, new)) != NULL) {
+ new = 0; /* for next time */
+
+ c = &d->sdb_component;
+ p = &c->product;
+
+ printf("%016llx:%08x @ %08llx-%08llx ",
+ ntohll(p->vendor_id), ntohl(p->device_id),
+ ntohll(c->addr_first), ntohll(c->addr_last));
+ printf("%.19s\n", p->name);
+ }
+ return 0;
+}
+
+static int bb_sdb_cat(char *sdbfile)
+{ char *buf;
+ int i, j;
+
+ /*
+ * Read a file, skipping trailing 0x00 or 0xff bytes, as a convenience.
+ * The function is based on bb::commands/cat (Sascha Hauer)
+ */
+ i = sdbfs_open_name(&bb_sdb_instance, sdbfile);
+ if (i < 0) {
+ printf("can't open \"%s\" in SDB device\n", sdbfile);
+ return COMMAND_ERROR;
+ }
+ buf = xmalloc(BUFSIZE);
+
+ while ( (i = sdbfs_fread(&bb_sdb_instance, -1, buf, BUFSIZE)) > 0) {
+
+ /* trim trailing garbage as the file is assumed to be text */
+ j = i - 1;
+ while (j > 0 && (buf[j] == 0xff || buf[j] == 0x00))
+ j--;
+ for (i = 0; i <= j; i++)
+ putchar(buf[i]);
+ /* no ctrl-C support; this is expected to be fast */
+ }
+ /* most files have the trailing newline already, avoid adding it */
+ free(buf);
+ sdbfs_close(&bb_sdb_instance);
+ return 0;
+}
+
+static int bb_sdb_set(char *varname, char *sdbfile)
+{
+ char *buf;
+ int i;
+
+ i = sdbfs_open_name(&bb_sdb_instance, sdbfile);
+ if (i < 0) {
+ printf("can't open \"%s\" in SDB device\n", sdbfile);
+ return COMMAND_ERROR;
+ }
+ buf = xmalloc(BUFSIZE);
+ i = sdbfs_fread(&bb_sdb_instance, -1, buf, BUFSIZE);
+ sdbfs_close(&bb_sdb_instance);
+
+ while (i > 0 && (buf[i - 1] == 0xff || buf[i - 1] == 0x00)) {
+ /* trim trailing garbage as the file is assumed to be text */
+ i--;
+ }
+ if (i > 0 && buf[i - 1] == '\n')
+ i--; /* remove trailing newline too */
+ buf[i] = '\0';
+ setenv(varname, buf);
+ free(buf);
+ sdbfs_close(&bb_sdb_instance);
+ return 0;
+}
+
+
+/* And finally the real command */
+static int do_sdb(int argc, char *argv[])
+{
+ unsigned long entrypoint = 0;
+ int fd, ret, opt;
+
+ while ((opt = getopt(argc, argv, "e:")) > 0) {
+ switch (opt) {
+ case 'e':
+ entrypoint = simple_strtoul(optarg, NULL, 0);
+ break;
+ default:
+ return COMMAND_ERROR_USAGE;
+ }
+ }
+ argc -= (optind - 1);
+ argv += (optind - 1);
+ if (argc < 3)
+ return COMMAND_ERROR_USAGE;
+
+ /* for all subcommands we neet to create the device */
+ fd = open(argv[2], O_RDONLY);
+
+ if (fd < 0) {
+ printf("could not open %s: %s\n", argv[2], errno_str());
+ return fd;
+ }
+ drvdata.fd = fd;
+ bb_sdb_instance.entrypoint = entrypoint;
+ ret = sdbfs_dev_create(&bb_sdb_instance, 0 /* not verbose */);
+ if (ret != 0) {
+ printf("Error accessing SDB filesystem in \"%s\"\n",
+ argv[2]);
+ return COMMAND_ERROR;
+ }
+
+ /* now do the three subcommands */
+ ret = COMMAND_ERROR_USAGE;
+ if (!strcmp(argv[1], "ls")) {
+ if (argc == 3)
+ ret = bb_sdb_ls();
+ } else if (!strcmp(argv[1], "cat")) {
+ if (argc == 4)
+ ret = bb_sdb_cat(argv[3]);
+ } else if (!strcmp(argv[1], "set")) {
+ if (argc == 4 || argc == 5)
+ ret = bb_sdb_set(argv[3], argv[4] ?: argv[3]);
+ }
+ sdbfs_dev_destroy(&bb_sdb_instance);
+ return ret;
+}
+
+
+
+static const __maybe_unused char cmd_sdb_help[] =
+"Usage: sdb [options] <command> <dev> [<sdbfile>]"
+"\n"
+"\"sdb [-e <entrypoint>] ls <dev>\" lists device content\n"
+"\"sdb [-e <entrypoint>] cat <dev> <sdbfile>\" prints a file\n"
+"\"sdb [-e <entrypoint>] set <dev> <varname> [<file>]\" sets var from SDB\n";
+
+BAREBOX_CMD_START(sdb)
+ .cmd = do_sdb,
+ .usage = "read/use SDB information in device",
+ BAREBOX_CMD_HELP(cmd_sdb_help)
+BAREBOX_CMD_END
--
1.7.10.4
From a6e098cc24afd466441dbec4e7843dc04717e672 Mon Sep 17 00:00:00 2001
From: Alessandro Rubini <rubini@gnudd.com>
Date: Mon, 15 Sep 2014 11:40:34 +0200
Subject: [PATCH 13/14] libsdb: integrate in build system
Signed-off-by: Alessandro Rubini <rubini@gnudd.com>
---
lib/Kconfig | 3 +++
lib/Makefile | 1 +
lib/sdb/Makefile | 44 +-------------------------------------------
3 files changed, 5 insertions(+), 43 deletions(-)
diff --git a/lib/Kconfig b/lib/Kconfig
index d9ad4aa..7a2884e 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -47,6 +47,9 @@ config LIBUBIGEN
config LIBMTD
bool
+config LIBSDB
+ bool
+
config STMP_DEVICE
bool
diff --git a/lib/Makefile b/lib/Makefile
index e8769a9..d4295fe 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -44,3 +44,4 @@ obj-y += gui/
obj-$(CONFIG_XYMODEM) += xymodem.o
obj-y += unlink-recursive.o
obj-$(CONFIG_STMP_DEVICE) += stmp-device.o
+obj-$(CONFIG_LIBSDB) += sdb/
diff --git a/lib/sdb/Makefile b/lib/sdb/Makefile
index 4699673..d3f06a4 100644
--- a/lib/sdb/Makefile
+++ b/lib/sdb/Makefile
@@ -1,43 +1 @@
-
-LINUX ?= /lib/modules/$(shell uname -r)/build
-
-# If we compile for the kernel, we need to include real kernel headers.
-# The thing is enough a mess that I moved it to a different file
-include Makefile.arch
-
-
-AS = $(CROSS_COMPILE)as
-LD = $(CROSS_COMPILE)ld
-CC = $(CROSS_COMPILE)gcc
-CPP = $(CC) -E
-AR = $(CROSS_COMPILE)ar
-NM = $(CROSS_COMPILE)nm
-STRIP = $(CROSS_COMPILE)strip
-OBJCOPY = $(CROSS_COMPILE)objcopy
-OBJDUMP = $(CROSS_COMPILE)objdump
-
-# calculate endianness at compile time
-ENDIAN := $(shell ./check-endian $(CC))
-
-CFLAGS = -Wall -ggdb -O2
-CFLAGS += -I../include/linux -I../include # for <sdb.h>
-CFLAGS += -ffunction-sections -fdata-sections
-CFLAGS += -Wno-pointer-sign
-CFLAGS += $(ENDIAN) $(LINUXINCLUDE)
-
-
-LIB = libsdbfs.a
-OBJS = glue.o access.o
-
-all: $(LIB)
-
-$(OBJS): $(wildcard *.h)
-
-$(LIB): $(OBJS)
- $(AR) r $@ $(OBJS)
-
-clean:
- rm -f $(OBJS) $(LIB) *~ core
-
-# add the other unused targets, so the rule in ../Makefile works
-modules install modules_install:
+obj-y += glue.o access.o
--
1.7.10.4
From 45c70af462edd6fb2cb6962545971a8a3ec78806 Mon Sep 17 00:00:00 2001
From: Alessandro Rubini <rubini@gnudd.com>
Date: Mon, 15 Sep 2014 11:40:59 +0200
Subject: [PATCH 14/14] commands: add sdb commands to list, read, setvar
Signed-off-by: Alessandro Rubini <rubini@gnudd.com>
---
commands/Kconfig | 7 ++
commands/Makefile | 1 +
commands/sdb.c | 220 +++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 228 insertions(+)
create mode 100644 commands/sdb.c
diff --git a/commands/Kconfig b/commands/Kconfig
index 352e8bf..89cadec 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -756,6 +756,13 @@ config CMD_DETECT
actual probe of the client devices until they are needed. Use the
'detect' command on the physical device to trigger probing.
+config CMD_SDB
+ bool
+ select LIBSDB
+ prompt "commands for reading SDB information"
+ help
+ This enables "sdbinfo", "sdbset" and "sdbread".
+
menuconfig CMD_WD
bool
depends on WATCHDOG
diff --git a/commands/Makefile b/commands/Makefile
index 91ec0e9..e97291e 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -91,6 +91,7 @@ obj-$(CONFIG_CMD_FILETYPE) += filetype.o
obj-$(CONFIG_CMD_BAREBOX_UPDATE)+= barebox-update.o
obj-$(CONFIG_CMD_MIITOOL) += miitool.o
obj-$(CONFIG_CMD_DETECT) += detect.o
+obj-$(CONFIG_CMD_SDB) += sdb.o
obj-$(CONFIG_CMD_BOOT) += boot.o
obj-$(CONFIG_CMD_DEVINFO) += devinfo.o
obj-$(CONFIG_CMD_READF) += readf.o
diff --git a/commands/sdb.c b/commands/sdb.c
new file mode 100644
index 0000000..6b8e358
--- /dev/null
+++ b/commands/sdb.c
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2014 CERN.
+ * Author: Alessandro Rubini for BE-CO-HT (White Rabbit project)
+ *
+ * Please use according to GNU GPL 2 or later
+ */
+#include <common.h>
+#include <command.h>
+#include <init.h>
+#include <malloc.h>
+#include <errno.h>
+#include <fs.h>
+#include <fcntl.h>
+#include <xfuncs.h>
+#include <environment.h>
+
+#include <../lib/sdb/libsdbfs.h> /* hackish */
+
+#define BUFSIZE 1024 /* like cat.c in this directory */
+
+/* This is the drvdata in the SDB information */
+struct bb_sdb_drvdata {
+ int fd;
+};
+
+static struct bb_sdb_drvdata drvdata;
+
+/* and how to read the thing: use straight barebox POSIX interface */
+static int bb_sdb_read(struct sdbfs *fs, int offset, void *buf, int count)
+{
+ struct bb_sdb_drvdata *dd = fs->drvdata;
+ int fd = dd->fd;
+
+ if (lseek(fd, offset, SEEK_SET) < 0)
+ return -1;
+ return read(fd, buf, count);
+}
+
+static struct sdbfs bb_sdb_instance = {
+ .drvdata = &drvdata,
+ .entrypoint = 0, /* unfortunately: to be fixed */
+ .read = bb_sdb_read,
+};
+
+/* local helpers to open and close, we do it three times on static data */
+static int bb_sdb_create(char *name)
+{
+ int fd, ret;
+ fd = open(name, O_RDONLY);
+
+ if (fd < 0) {
+ printf("could not open %s: %s\n", name, errno_str());
+ return fd;
+ }
+ drvdata.fd = fd;
+ ret = sdbfs_dev_create(&bb_sdb_instance, 1 /* verbose */);
+ if (ret != 0) {
+ printf("Error accessing SDB filesystem in \"%s\"\n",
+ name);
+ }
+ return ret;
+}
+
+static int bb_sdb_destroy(void)
+{
+ return sdbfs_dev_destroy(&bb_sdb_instance);
+}
+
+/* And finally the real commands */
+static int do_sdbinfo(int argc, char *argv[])
+{
+ struct sdb_device *d;
+ struct sdb_product *p;
+ struct sdb_component *c;
+ int new;
+
+ if (argc != 2) {
+ perror("sdbinfo");
+ return 1;
+ }
+ if (bb_sdb_create(argv[1]) != 0)
+ return 1;
+ /* now we already identified the magic number and so on */
+
+ new = 1;
+ while ( (d = sdbfs_scan(&bb_sdb_instance, new)) != NULL) {
+ new = 0; /* for next time */
+
+ c = &d->sdb_component;
+ p = &c->product;
+
+ printf("%016llx:%08x @ %08llx-%08llx ",
+ ntohll(p->vendor_id), ntohl(p->device_id),
+ ntohll(c->addr_first), ntohll(c->addr_last));
+ printf("%.19s\n", p->name);
+ }
+ return bb_sdb_destroy();
+}
+
+static int do_sdbset(int argc, char *argv[])
+{
+ char *buf;
+ char *filename;
+ int i, j, err = 1;
+
+ if (argc < 3 || argc > 4) {
+ perror("sdbset");
+ return 1;
+ }
+ if (bb_sdb_create(argv[1]) != 0)
+ return 1;
+ /* now we already identified the magic number and so on */
+
+ filename = argv[argc - 1];
+ i = sdbfs_open_name(&bb_sdb_instance, filename);
+ if (i < 0) {
+ printf("can't open \"%s\" in \"%s\"\n", filename, argv[1]);
+ goto out;
+ }
+ buf = xmalloc(BUFSIZE);
+ i = sdbfs_fread(&bb_sdb_instance, -1, buf, BUFSIZE);
+ sdbfs_close(&bb_sdb_instance);
+
+ if (i > 0) {
+ j = i - 1;
+ /* trim trailing garbage as the file is assumed to be text */
+ while (j && (buf[j] == 0xff || buf[j] == 0x00))
+ j--;
+ }
+ if (i > 0 && buf[i - 1] == '\n')
+ i--; /* remove trailing newline too */
+ if (i > 0) {
+ buf[i] = '\0';
+ setenv(argv[2], buf);
+ }
+ free(buf);
+ sdbfs_close(&bb_sdb_instance);
+ err = 0;
+out:
+ bb_sdb_destroy();
+ return err;
+}
+
+/*
+ * Read a file, skipping trailing 0x00 or 0xff bytes, as a convenience.
+ * The function is based on local command cat, in this director (Sascha Hauer)
+ */
+static int do_sdbread(int argc, char *argv[])
+{
+ char *buf;
+ int i, j, err = 1;
+
+ if (argc != 3) {
+ perror("sdbread");
+ return 1;
+ }
+
+ if (bb_sdb_create(argv[1]) != 0)
+ return 1;
+ /* now we already identified the magic number and so on */
+
+ i = sdbfs_open_name(&bb_sdb_instance, argv[2]);
+ if (i < 0) {
+ printf("can't open \"%s\" in \"%s\"\n", argv[2], argv[1]);
+ goto out;
+ }
+ buf = xmalloc(BUFSIZE);
+
+ while ( (i = sdbfs_fread(&bb_sdb_instance, -1, buf, BUFSIZE)) > 0) {
+
+ /* trim trailing garbage as the file is assumed to be text */
+ j = i - 1;
+ while (j > 0 && (buf[j] == 0xff || buf[j] == 0x00))
+ j--;
+ for (i = 0; i <= j; i++)
+ putchar(buf[i]);
+ /* no ctrl-C support; this is expected to be fast */
+ }
+ /* most files have the trailing newline alrady, avoid adding it */
+ free(buf);
+ sdbfs_close(&bb_sdb_instance);
+ err = 0;
+out:
+ bb_sdb_destroy();
+ return err;
+}
+
+static const __maybe_unused char cmd_sdbinfo_help[] =
+"Usage: sdbinfo <dev>"
+"\n"
+"List SDB files inside <dev>. Currently entry point must be zero";
+
+BAREBOX_CMD_START(sdbinfo)
+ .cmd = do_sdbinfo,
+ .usage = "sdb information in device",
+ BAREBOX_CMD_HELP(cmd_sdbinfo_help)
+BAREBOX_CMD_END
+
+static const __maybe_unused char cmd_sdbset_help[] =
+"Usage: sdbset <dev> <varname> [<sdbfile>]"
+"\n"
+"Set a variable from the content of an SDB file in <dev>\n";
+
+BAREBOX_CMD_START(sdbset)
+ .cmd = do_sdbset,
+ .usage = "set a variable from an SDB file",
+ BAREBOX_CMD_HELP(cmd_sdbset_help)
+BAREBOX_CMD_END
+
+static const __maybe_unused char cmd_sdbread_help[] =
+"Usage: sdbread <dev> <file>"
+"\n"
+"Print contents of file to stdout\n";
+
+BAREBOX_CMD_START(sdbread)
+ .cmd = do_sdbread,
+ .usage = "cat an SDB file",
+ BAREBOX_CMD_HELP(cmd_sdbread_help)
+BAREBOX_CMD_END
+
--
1.7.10.4
......@@ -309,6 +309,7 @@ CONFIG_CMD_GPIO=y
# CONFIG_CMD_SPI is not set
# CONFIG_CMD_MIITOOL is not set
# CONFIG_CMD_DETECT is not set
CONFIG_CMD_SDB=y
CONFIG_NET=y
CONFIG_NET_DHCP=y
CONFIG_NET_NFS=y
......@@ -493,6 +494,7 @@ CONFIG_LZO_DECOMPRESS=y
CONFIG_LIBSCAN=y
CONFIG_LIBUBIGEN=y
CONFIG_LIBMTD=y
CONFIG_LIBSDB=y
#
# Library gui routines
......
From dc89605b7cb7be4e1bad004b689222fcef15678a Mon Sep 17 00:00:00 2001
From a15f036b4e47dcbc8e9f4b739605975658ddb61f Mon Sep 17 00:00:00 2001
From: Alessandro Rubini <rubini@gnudd.com>
Date: Sat, 21 Jun 2014 08:48:04 +0200
Subject: [PATCH 11/11] sam9m10g45ek (for wrs): final partitions for V4
Subject: [PATCH 11/12] sam9m10g45ek (for wrs): final partitions for V4.1
This changes the partitions in an incompatible way: then NAND
now has one partition for barebox environment (1M: 5 blocks to
......@@ -9,16 +9,39 @@ protect against bad blocks) and one big partition fro UBI volumes.
Real stuff is then split in UBI volumes. Please see documentation
(in a later commit) for details.
Also, this adds the read-only hwinfo in dataflash, for V4.1 stuff.
Signed-off-by: Alessandro Rubini <rubini@gnudd.com>
---
arch/arm/mach-at91/board-sam9m10g45ek.c | 12 +-----------
1 files changed, 1 insertions(+), 11 deletions(-)
arch/arm/mach-at91/board-sam9m10g45ek.c | 19 ++++++++-----------
1 file changed, 8 insertions(+), 11 deletions(-)
diff --git a/arch/arm/mach-at91/board-sam9m10g45ek.c b/arch/arm/mach-at91/board-sam9m10g45ek.c
index afc6418..2eb70d5 100644
index afc6418..552c209 100644
--- a/arch/arm/mach-at91/board-sam9m10g45ek.c
+++ b/arch/arm/mach-at91/board-sam9m10g45ek.c
@@ -167,18 +167,8 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
@@ -26,6 +26,7 @@
#include <linux/clk.h>
#include <linux/atmel-mci.h>
#include <linux/spi/flash.h>
+#include <linux/mtd/mtd.h>
#include <mach/hardware.h>
#include <video/atmel_lcdc.h>
@@ -106,6 +107,12 @@ static struct mtd_partition wrs_df_parts[] = {
.size = 0x8400,
},
{
+ .name = "hwinfo",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 0x840,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ {
.name = "Available-dataflash",
.offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL,
@@ -167,18 +174,8 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
.size = SZ_1M,
},
{
......@@ -39,5 +62,5 @@ index afc6418..2eb70d5 100644
},
};
--
1.7.7.2
1.7.10.4
......@@ -12,7 +12,8 @@ WR_INSTALL_ROOT ?= $(WRS_OUTPUT_DIR)/images/wr
WRDEV_DIR ?= $(WRS_BASE_DIR)/..
# subdirectories we want to compile
SUBDIRS = libptpnetif mini-rpc libswitchhw wrsw_hal wrsw_rtud tools snmpd
SUBDIRS = libptpnetif mini-rpc libswitchhw libsdb \
wrsw_hal wrsw_rtud tools snmpd
# all variables are exported
export
......
/*
* This is the official version 1.1 of sdb.h
*/
#ifndef __SDB_H__
#define __SDB_H__
#ifdef __KERNEL__
#include <linux/types.h>
#else
#include <stdint.h>
#endif
/*
* All structures are 64 bytes long and are expected
* to live in an array, one for each interconnect.
* Most fields of the structures are shared among the
* various types, and most-specific fields are at the
* beginning (for alignment reasons, and to keep the
* magic number at the head of the interconnect record
*/
/* Product, 40 bytes at offset 24, 8-byte aligned
*
* device_id is vendor-assigned; version is device-specific,
* date is hex (e.g 0x20120501), name is UTF-8, blank-filled
* and not terminated with a 0 byte.
*/
struct sdb_product {
uint64_t vendor_id; /* 0x18..0x1f */
uint32_t device_id; /* 0x20..0x23 */
uint32_t version; /* 0x24..0x27 */
uint32_t date; /* 0x28..0x2b */
uint8_t name[19]; /* 0x2c..0x3e */
uint8_t record_type; /* 0x3f */
};
/*
* Component, 56 bytes at offset 8, 8-byte aligned
*
* The address range is first to last, inclusive
* (for example 0x100000 - 0x10ffff)
*/
struct sdb_component {
uint64_t addr_first; /* 0x08..0x0f */
uint64_t addr_last; /* 0x10..0x17 */
struct sdb_product product; /* 0x18..0x3f */
};
/* Type of the SDB record */
enum sdb_record_type {
sdb_type_interconnect = 0x00,
sdb_type_device = 0x01,
sdb_type_bridge = 0x02,
sdb_type_integration = 0x80,
sdb_type_repo_url = 0x81,
sdb_type_synthesis = 0x82,
sdb_type_empty = 0xFF,
};
/* Type 0: interconnect (first of the array)
*
* sdb_records is the length of the table including this first
* record, version is 1. The bus type is enumerated later.
*/
#define SDB_MAGIC 0x5344422d /* "SDB-" */
struct sdb_interconnect {
uint32_t sdb_magic; /* 0x00-0x03 */
uint16_t sdb_records; /* 0x04-0x05 */
uint8_t sdb_version; /* 0x06 */
uint8_t sdb_bus_type; /* 0x07 */
struct sdb_component sdb_component; /* 0x08-0x3f */
};
/* Type 1: device
*
* class is 0 for "custom device", other values are
* to be standardized; ABI version is for the driver,
* bus-specific bits are defined by each bus (see below)
*/
struct sdb_device {
uint16_t abi_class; /* 0x00-0x01 */
uint8_t abi_ver_major; /* 0x02 */
uint8_t abi_ver_minor; /* 0x03 */
uint32_t bus_specific; /* 0x04-0x07 */
struct sdb_component sdb_component; /* 0x08-0x3f */
};
/* Type 2: bridge
*
* child is the address of the nested SDB table
*/
struct sdb_bridge {
uint64_t sdb_child; /* 0x00-0x07 */
struct sdb_component sdb_component; /* 0x08-0x3f */
};
/* Type 0x80: integration
*
* all types with bit 7 set are meta-information, so
* software can ignore the types it doesn't know. Here we
* just provide product information for an aggregate device
*/
struct sdb_integration {
uint8_t reserved[24]; /* 0x00-0x17 */
struct sdb_product product; /* 0x08-0x3f */
};
/* Type 0x81: Top module repository url
*
* again, an informative field that software can ignore
*/
struct sdb_repo_url {
uint8_t repo_url[63]; /* 0x00-0x3e */
uint8_t record_type; /* 0x3f */
};
/* Type 0x82: Synthesis tool information
*
* this informative record
*/
struct sdb_synthesis {
uint8_t syn_name[16]; /* 0x00-0x0f */
uint8_t commit_id[16]; /* 0x10-0x1f */
uint8_t tool_name[8]; /* 0x20-0x27 */
uint32_t tool_version; /* 0x28-0x2b */
uint32_t date; /* 0x2c-0x2f */
uint8_t user_name[15]; /* 0x30-0x3e */
uint8_t record_type; /* 0x3f */
};
/* Type 0xff: empty
*
* this allows keeping empty slots during development,
* so they can be filled later with minimal efforts and
* no misleading description is ever shipped -- hopefully.
* It can also be used to pad a table to a desired length.
*/
struct sdb_empty {
uint8_t reserved[63]; /* 0x00-0x3e */
uint8_t record_type; /* 0x3f */
};
/* The type of bus, for bus-specific flags */
enum sdb_bus_type {
sdb_wishbone = 0x00,
sdb_data = 0x01,
};
#define SDB_WB_WIDTH_MASK 0x0f
#define SDB_WB_ACCESS8 0x01
#define SDB_WB_ACCESS16 0x02
#define SDB_WB_ACCESS32 0x04
#define SDB_WB_ACCESS64 0x08
#define SDB_WB_LITTLE_ENDIAN 0x80
#define SDB_DATA_READ 0x04
#define SDB_DATA_WRITE 0x02
#define SDB_DATA_EXEC 0x01
#endif /* __SDB_H__ */
LINUX ?= /lib/modules/$(shell uname -r)/build
# If we compile for the kernel, we need to include real kernel headers.
# The thing is enough a mess that I moved it to a different file
include Makefile.arch
AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
CC = $(CROSS_COMPILE)gcc
CPP = $(CC) -E
AR = $(CROSS_COMPILE)ar
NM = $(CROSS_COMPILE)nm
STRIP = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
# calculate endianness at compile time
ENDIAN := $(shell ./check-endian $(CC))
CFLAGS = -Wall -ggdb -O2
CFLAGS += -I../include/linux -I../include # for <sdb.h>
CFLAGS += -ffunction-sections -fdata-sections
CFLAGS += -Wno-pointer-sign
CFLAGS += $(ENDIAN) $(LINUXINCLUDE)
LIB = libsdbfs.a
OBJS = glue.o access.o
all: $(LIB)
$(OBJS): $(wildcard *.h)
$(LIB): $(OBJS)
$(AR) r $@ $(OBJS)
clean:
rm -f $(OBJS) $(LIB) *~ core
# add the other unused targets, so the rule in ../Makefile works
modules install modules_install:
srctree = $(LINUX)
#
# This set of contortions comes from the kernel Makefile. We need this
# in order to properly compile libsdbfs for the kernel without being
# in a kernel build environment (for example, to check for compile errors).
#
ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
-e s/arm.*/arm/ -e s/sa110/arm/ \
-e s/s390x/s390/ -e s/parisc64/parisc/ \
-e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
-e s/sh[234].*/sh/ )
SRCARCH := $(ARCH)
# Additional ARCH settings for x86
ifeq ($(ARCH),i386)
SRCARCH := x86
endif
ifeq ($(ARCH),x86_64)
SRCARCH := x86
endif
# Additional ARCH settings for sparc
ifeq ($(ARCH),sparc32)
SRCARCH := sparc
endif
ifeq ($(ARCH),sparc64)
SRCARCH := sparc
endif
# Additional ARCH settings for sh
ifeq ($(ARCH),sh64)
SRCARCH := sh
endif
# Additional ARCH settings for tile
ifeq ($(ARCH),tilepro)
SRCARCH := tile
endif
ifeq ($(ARCH),tilegx)
SRCARCH := tile
endif
# Where to locate arch specific headers
hdr-arch := $(SRCARCH)
ifeq ($(ARCH),m68knommu)
hdr-arch := m68k
endif
# Use LINUXINCLUDE when you must reference the include/ directory.
# Needed to be compatible with the O= option
LINUXINCLUDE := -I$(srctree)/arch/$(hdr-arch)/include \
-Iarch/$(hdr-arch)/include/generated \
-I$(srctree)/include
/*
* Copyright (C) 2012,2013 CERN (www.cern.ch)
* Author: Alessandro Rubini <rubini@gnudd.com>
*
* Released according to the GNU GPL, version 2 or any later version.
*
* This work is part of the White Rabbit project, a research effort led
* by CERN, the European Institute for Nuclear Research.
*/
/* To avoid many #ifdef and associated mess, all headers are included there */
#include "libsdbfs.h"
int sdbfs_fstat(struct sdbfs *fs, struct sdb_device *record_return)
{
if (!fs->currentp)
return -ENOENT;
memcpy(record_return, fs->currentp, sizeof(*record_return));
return 0;
}
int sdbfs_fread(struct sdbfs *fs, int offset, void *buf, int count)
{
int ret;
if (!fs->currentp)
return -ENOENT;
if (offset < 0)
offset = fs->read_offset;
if (offset + count > fs->f_len)
count = fs->f_len - offset;
ret = count;
if (fs->data)
memcpy(buf, fs->data + fs->f_offset + offset, count);
else
ret = fs->read(fs, fs->f_offset + offset, buf, count);
if (ret > 0)
fs->read_offset = offset + ret;
return ret;
}
int sdbfs_fwrite(struct sdbfs *fs, int offset, void *buf, int count)
{
int ret;
if (!fs->currentp)
return -ENOENT;
if (offset < 0)
offset = fs->read_offset;
if (offset + count > fs->f_len)
count = fs->f_len - offset;
ret = count;
if (fs->data)
memcpy(buf, fs->data + fs->f_offset + offset, count);
else
ret = fs->write(fs, fs->f_offset + offset, buf, count);
if (ret > 0)
fs->read_offset = offset + ret;
return ret;
}
#!/bin/bash
# Check endianness at compile time, so we can pass the -D to CFLAGS
CC=$1
if [ "x$CC" == "x" ]; then
echo "$0: pass the compiler path (\$CC) as argument" >& 2
exit 1
fi
# Check endianness, by making an object file
TMPC=$(mktemp /tmp/endian-c-XXXXXX)
TMPO=$(mktemp /tmp/endian-o-XXXXXX)
echo "int i = 0xbbee;" > $TMPC
$CC -x c -c $TMPC -o $TMPO
OBJCOPY=$(echo $CC | sed 's/gcc$/objcopy/')
if $OBJCOPY -O binary $TMPO /dev/stdout | od -t x1 -An | \
grep -q 'bb ee'; then
echo " -DSDBFS_BIG_ENDIAN"
else
echo " -DSDBFS_LITTLE_ENDIAN"
fi
rm -f $TMPC $TMPO
/*
* Copyright (C) 2012,2014 CERN (www.cern.ch)
* Author: Alessandro Rubini <rubini@gnudd.com>
*
* Released according to the GNU GPL, version 2 or any later version.
*
* This work is part of the White Rabbit project, a research effort led
* by CERN, the European Institute for Nuclear Research.
*/
/* To avoid many #ifdef and associated mess, all headers are included there */
#include "libsdbfs.h"
static struct sdbfs *sdbfs_list;
/* All fields unused by the caller are expected to be zeroed */
int sdbfs_dev_create(struct sdbfs *fs, int verbose)
{
unsigned int magic;
/* First, check we have the magic */
if (fs->data)
magic = *(unsigned int *)(fs->data + fs->entrypoint);
else
fs->read(fs, fs->entrypoint, &magic, sizeof(magic));
if (magic == SDB_MAGIC) {
/* Uh! If we are little-endian, we must convert */
if (ntohl(1) != 1)
fs->flags |= SDBFS_F_CONVERT32;
} else if (htonl(magic) == SDB_MAGIC) {
/* ok, don't convert */
} else {
return -ENOTDIR;
}
if (verbose)
fs->flags |= SDBFS_F_VERBOSE;
fs->next = sdbfs_list;
sdbfs_list = fs;
return 0;
}
int sdbfs_dev_destroy(struct sdbfs *fs)
{
struct sdbfs **p;
for (p = &sdbfs_list; *p && *p != fs; p = &(*p)->next)
;
if (!*p)
return -ENOENT;
*p = fs->next;
return 0;
}
struct sdbfs *sdbfs_dev_find(const char *name)
{
struct sdbfs *l;
for (l = sdbfs_list; l && strcmp(l->name, name); l = l->next)
;
if (!l)
return NULL;
return l;
}
/*
* To open by name or by ID we need to scan the tree. The scan
* function is also exported in order for "sdb-ls" to use it
*/
static struct sdb_device *sdbfs_readentry(struct sdbfs *fs,
unsigned long offset)
{
/*
* This function reads an entry from a known good offset. It
* returns the pointer to the entry, which may be stored in
* the fs structure itself. Only touches fs->current_record.
*/
if (fs->data) {
if (!(fs->flags & SDBFS_F_CONVERT32))
return (struct sdb_device *)(fs->data + offset);
/* copy to local storage for conversion */
memcpy(&fs->current_record, fs->data + offset,
sizeof(fs->current_record));
} else {
if (!fs->read)
return NULL;
fs->read(fs, offset, &fs->current_record,
sizeof(fs->current_record));
}
if (fs->flags & SDBFS_F_CONVERT32) {
uint32_t *p = (void *)&fs->current_record;
int i;
for (i = 0; i < sizeof(fs->current_record) / sizeof(*p); i++)
p[i] = ntohl(p[i]);
}
return &fs->current_record;
}
/* Helper for scanning: we enter a new directory, and we must validate */
static struct sdb_device *scan_newdir(struct sdbfs *fs, int depth)
{
struct sdb_device *dev;
struct sdb_interconnect *intercon;
dev = fs->currentp = sdbfs_readentry(fs, fs->this[depth]);
if (dev->sdb_component.product.record_type != sdb_type_interconnect)
return NULL;
intercon = (typeof(intercon))dev;
if (ntohl(intercon->sdb_magic) != SDB_MAGIC)
return NULL;
fs->nleft[depth] = ntohs(intercon->sdb_records) - 1;
fs->this[depth] += sizeof(*intercon);
fs->depth = depth;
return dev;
}
struct sdb_device *sdbfs_scan(struct sdbfs *fs, int newscan)
{
/*
* This returns a pointer to the next sdb record, or the first one.
* Subdirectories (bridges) are returned before their contents.
* It only uses internal fields.
*/
struct sdb_device *dev;
struct sdb_bridge *bridge;
int depth, type, newdir = 0; /* check there's the magic */
if (newscan) {
fs->base[0] = 0;
fs->this[0] = fs->entrypoint;
depth = fs->depth = 0;
newdir = 1;
goto scan;
}
/* If we already returned a bridge, go inside it (check type) */
depth = fs->depth;
type = fs->currentp->sdb_component.product.record_type;
if (type == sdb_type_bridge && depth + 1 < SDBFS_DEPTH) {
bridge = (typeof(bridge))fs->currentp;
fs->this[depth + 1] = fs->base[depth]
+ ntohll(bridge->sdb_child);
fs->base[depth + 1] = fs->base[depth]
+ ntohll(bridge->sdb_component.addr_first);
depth++;
newdir++;
}
scan:
/* If entering a new directory, verify magic and set nleft */
if (newdir) {
dev = scan_newdir(fs, depth);
if (dev)
return dev;
/* Otherwise the directory is not there: no intercon */
if (!depth)
return NULL; /* no entries at all */
depth--;
}
while (fs->nleft[depth] == 0) {
/* No more at this level, "cd .." if possible */
if (!depth)
return NULL;
fs->depth = --depth;
}
/* so, read the next entry */
dev = fs->currentp = sdbfs_readentry(fs, fs->this[depth]);
fs->this[depth] += sizeof(*dev);
fs->nleft[depth]--;
return dev;
}
static void __open(struct sdbfs *fs)
{
fs->f_offset = fs->base[fs->depth]
+ htonll(fs->currentp->sdb_component.addr_first);
fs->f_len = htonll(fs->currentp->sdb_component.addr_last)
+ 1 - htonll(fs->currentp->sdb_component.addr_first);
fs->read_offset = 0;
}
int sdbfs_open_name(struct sdbfs *fs, const char *name)
{
struct sdb_device *d;
int len = strlen(name);
if (len > 19)
return -ENOENT;
sdbfs_scan(fs, 1); /* new scan: get the interconnect and igore it */
while ( (d = sdbfs_scan(fs, 0)) != NULL) {
if (strncmp(name, d->sdb_component.product.name, len))
continue;
if (len < 19 && d->sdb_component.product.name[len] != ' ')
continue;
fs->currentp = d;
__open(fs);
return 0;
}
return -ENOENT;
}
int sdbfs_open_id(struct sdbfs *fs, uint64_t vid, uint32_t did)
{
struct sdb_device *d;
sdbfs_scan(fs, 1); /* new scan: get the interconnect and igore it */
while ( (d = sdbfs_scan(fs, 0)) != NULL) {
if (vid != d->sdb_component.product.vendor_id)
continue;
if (did != d->sdb_component.product.device_id)
continue;
fs->currentp = d;
__open(fs);
return 0;
}
return -ENOENT;
}
int sdbfs_close(struct sdbfs *fs)
{
fs->currentp = NULL;
return 0;
}
/* Though freestanding, some minimal headers are expected to exist */
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#define SDB_KERNEL 0
#define SDB_USER 0
#define SDB_FREESTAND 1
#ifdef SDBFS_BIG_ENDIAN
# define ntohs(x) (x)
# define htons(x) (x)
# define ntohl(x) (x)
# define htonl(x) (x)
#else
# error "No support, yet, for little-endian freestanding library"
#endif
/*
* This supports both the Linux kernel and barebox, that is similar
* by design, and defines __KERNEL__ too.
*/
#ifdef __BAREBOX__
# include <errno.h>
#else /* really linux */
# include <linux/errno.h>
#endif
#include <linux/types.h>
#include <linux/string.h>
#include <asm/byteorder.h>
/*
* The default installed /usr/include/linux stuff misses the __KERNEL__ parts.
* For libsdbfs it means we won't get uint32_t and similar types.
*
* So, check if we got the information we need before strange errors happen.
* The DECLARE_BITMAP macro is in <linux/types.h> since the epoch, but it
* is not installed in /usr/include/linux/types.h, so use it to check.
*
* If building for barebox, we miss the macro, but we are sure that
* we are picking the correct header, because the library is only built
* within the barebox source tree.
*/
#if !defided(DECLARE_BITMAP) && !defined(__BAREBOX__)
# error "Please point LINUX to a source tree if you define __KERNEL__"
#endif
#define SDB_KERNEL 1
#define SDB_USER 0
#define SDB_FREESTAND 0
#define sdb_print(format, ...) printk(format, __VA_ARGS__)
#ifndef __LIBSDBFS_USER_H__
#define __LIBSDBFS_USER_H__
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <arpa/inet.h> /* htonl */
#define SDB_KERNEL 0
#define SDB_USER 1
#define SDB_FREESTAND 0
#define sdb_print(format, ...) fprintf(stderr, format, __VA_ARGS__)
#endif /* __LIBSDBFS_USER_H__ */
#ifndef __LIBSDBFS_H__
#define __LIBSDBFS_H__
/* The library can work in different environments, take care of them */
#ifdef __KERNEL__
# include "libsdbfs-kernel.h"
#elif defined(__unix__)
# include "libsdbfs-user.h"
#else
# include "libsdbfs-freestanding.h"
#endif
#include <sdb.h> /* Please point your "-I" to some sensible place */
#define SDBFS_DEPTH 4 /* Max number of subdirectory depth */
/*
* Data structures: please not that the library intself doesn't use
* malloc, so it's the caller who must deal withallocation/removal.
* For this reason we can have no opaque structures, but some fields
* are private
*/
struct sdbfs {
/* Some fields are informative */
char *name; /* may be null */
void *drvdata; /* driver may need some detail.. */
unsigned long blocksize;
unsigned long entrypoint;
/* The "driver" must offer some methods */
void *data; /* Use this if directly mapped */
unsigned long datalen; /* Length of the above array */
int (*read)(struct sdbfs *fs, int offset, void *buf, int count);
int (*write)(struct sdbfs *fs, int offset, void *buf, int count);
int (*erase)(struct sdbfs *fs, int offset, int count);
/* All fields from here onwards are library-private */
struct sdb_device *currentp;
struct sdb_device current_record;
unsigned long f_len;
unsigned long f_offset; /* start of file */
unsigned long read_offset; /* current location */
unsigned long flags;
struct sdbfs *next;
/* The following ones are directory-aware */
unsigned long base[SDBFS_DEPTH]; /* for relative addresses */
unsigned long this[SDBFS_DEPTH]; /* current sdb record */
int nleft[SDBFS_DEPTH];
int depth;
};
#define SDBFS_F_VERBOSE 0x0001
#define SDBFS_F_CONVERT32 0x0002 /* swap SDB words as they are read */
/* Defined in glue.c */
int sdbfs_dev_create(struct sdbfs *fs, int verbose);
int sdbfs_dev_destroy(struct sdbfs *fs);
struct sdbfs *sdbfs_dev_find(const char *name);
int sdbfs_open_name(struct sdbfs *fs, const char *name);
int sdbfs_open_id(struct sdbfs *fs, uint64_t vid, uint32_t did);
int sdbfs_close(struct sdbfs *fs);
struct sdb_device *sdbfs_scan(struct sdbfs *fs, int newscan);
/* Defined in access.c */
int sdbfs_fstat(struct sdbfs *fs, struct sdb_device *record_return);
int sdbfs_fread(struct sdbfs *fs, int offset, void *buf, int count);
int sdbfs_fwrite(struct sdbfs *fs, int offset, void *buf, int count);
/* This is needed to convert endianness. Hoping it is not defined elsewhere */
static inline uint64_t htonll(uint64_t ll)
{
uint64_t res;
if (htonl(1) == 1)
return ll;
res = htonl(ll >> 32);
res |= (uint64_t)(htonl((uint32_t)ll)) << 32;
return res;
}
static inline uint64_t ntohll(uint64_t ll)
{
return htonll(ll);
}
#endif /* __LIBSDBFS_H__ */
......@@ -21,7 +21,7 @@
<?php $_SESSION['advance']=""; ?>
<p><strong>WRSW OS: <?php $str = shell_exec("uname -r"); echo $str; ?> </strong></p>
<p><strong><?php $str = shell_exec("/wr/bin/wrsw_version -g"); $str = str_replace("\n","<br>",$str);
<p><strong><?php $str = shell_exec("/wr/bin/wrs_version -g"); $str = str_replace("\n","<br>",$str);
$str=str_replace("Reading GW info","",$str); echo $str; ?></strong></p><p>&nbsp;</p>
<br>
<center><p align=right><strong>Open Hardware Repository <a href="http://www.ohwr.org/projects/white-rabbit/wiki">http://www.ohwr.org/projects/white-rabbit/wiki</a> </strong></p></strong></p><p>&nbsp;</p>
......
......@@ -26,10 +26,10 @@
<?php
if(!strcmp($_GET['vlan'],"all")){ // Delete all vlans and free ports
shell_exec("/wr/bin/wrsw_vlans --clear");
shell_exec("/wr/bin/wrs_vlans --clear");
}else{
shell_exec("/wr/bin/wrsw_vlans --rvid ".$_GET['vlan']." --del");
shell_exec("/wr/bin/wrs_vlans --rvid ".$_GET['vlan']." --del");
}
......
......@@ -109,7 +109,7 @@ function wrs_header_ports(){
* @author José Luis Gutiérrez <jlgutierrez@ugr.es>
*
* Displays the info comming from the following commands:
* uname, wrsw_version, wr_date and php.ini
* uname, wrs_version, wr_date and php.ini
*
*/
function wrs_main_info(){
......@@ -140,13 +140,13 @@ function wrs_main_info(){
//echo '<tr><th> <b>OS name:</b> </th><th><center>'; $str = shell_exec("uname -s"); echo $str; echo '</center></th></tr>';
echo '<tr><th align=center> <b><font color="darkblue">Kernel Version</font></b> </th><th><center>'; $str = shell_exec("uname -r"); echo $str; $str = shell_exec("uname -v"); echo $str; echo '</center></th></tr>';
echo '<tr><th align=center> <b><font color="darkblue">Firmware Version</font></b> </th><th><center> '; $str = shell_exec("/wr/bin/wrsw_version | awk '{print $4}'");
echo '<tr><th align=center> <b><font color="darkblue">Firmware Version</font></b> </th><th><center> '; $str = shell_exec("/wr/bin/wrs_version | awk '{print $4}'");
echo '<a href="showfile.php?help_id=gateware&name=GateWare Info" onClick="showPopup(this.href);return(false);"</a>';
echo $str; echo '</center></th></tr>';
echo '<tr><th align=center> <b><font color="darkblue">PCB Version</font></b> </th><th><center>'; $str = shell_exec("/wr/bin/wrsw_version -p"); echo $str; echo '</center></th></tr>';
echo '<tr><th align=center> <b><font color="darkblue">FPGA</font></b> </th><th><center>'; $str = shell_exec("/wr/bin/wrsw_version -f"); echo $str; echo '</center></th></tr>';
echo '<tr><th align=center> <b><font color="darkblue">Compiling Date</font></b> </th><th><center>'; $str = shell_exec("/wr/bin/wrsw_version -c"); echo $str; echo '</center></th></tr>';
echo '<tr><th align=center> <b><font color="darkblue">PCB Version</font></b> </th><th><center>'; $str = shell_exec("/wr/bin/wrs_version -p"); echo $str; echo '</center></th></tr>';
echo '<tr><th align=center> <b><font color="darkblue">FPGA</font></b> </th><th><center>'; $str = shell_exec("/wr/bin/wrs_version -f"); echo $str; echo '</center></th></tr>';
echo '<tr><th align=center> <b><font color="darkblue">Compiling Date</font></b> </th><th><center>'; $str = shell_exec("/wr/bin/wrs_version -c"); echo $str; echo '</center></th></tr>';
echo '<tr><th align=center> <b><font color="darkblue">White-Rabbit Date</font></b></th><th><center>'; $str = shell_exec("export TZ=".$_SESSION['utc']." /wr/bin/wr_date -n get"); echo str_replace("\n","<br>",$str); echo '</center></th></tr>';
echo '<tr><th align=center> <b><font color="darkblue">PPSi</font></b> </th><th><center>'; echo wrs_check_ptp_status() ? '[<A HREF="ptp.php">on</A>]' : '[<A HREF="ptp.php">off</A>]'; echo '</center></th></tr>';
echo '<tr><th align=center> <b><font color="darkblue">Net-SNMP Server</font></b> </th><th><center>'; echo check_snmp_status() ? '[on] ' : '[off] '; echo '&nbsp;&nbsp;ver. '; echo shell_exec("snmpd -v | grep version | awk '{print $3}'");
......@@ -1051,7 +1051,7 @@ function wrs_display_help($help_id, $name){
$message = "<p>This is a switch console emulator windows. Use it as if you were using a ssh session.</p>";
} else if (!strcmp($help_id, "gateware")){
$msg = shell_exec("/wr/bin/wrsw_version -g");
$msg = shell_exec("/wr/bin/wrs_version -g");
$msg = explode("\n", $msg);
for($i=0; $i<5; $i++){
......
......@@ -25,7 +25,7 @@
<?php
$vlan_cmd = "/wr/bin/wrsw_vlans ";
$vlan_cmd = "/wr/bin/wrs_vlans ";
if(!empty($_POST['vid'])){ $vlan_cmd .= " --rvid ".$_POST['vid'];}
if(!empty($_POST['fid'])){$vlan_cmd .= " --rfid ".$_POST['fid'];}
if(!empty($_POST['mask'])){$vlan_cmd .= " --rmask ".$_POST['mask'];}
......
......@@ -26,7 +26,7 @@
// Get VLANS
echo '<center><strong>Port-VLAN List</strong></center><hr>';
$tmp_vlan_file="/tmp/vlans.conf";
$vlans = shell_exec("/wr/bin/wrsw_vlans --list >".$tmp_vlan_file);
$vlans = shell_exec("/wr/bin/wrs_vlans --list >".$tmp_vlan_file);
$vlans = shell_exec("cat ".$tmp_vlan_file." | sed -n '/ /s/ \+/ /gp'");
$vlans = explode("\n", $vlans);
$name_vlans="";
......@@ -44,7 +44,7 @@
// Get Previous assignment
$tmp_assign_file="/tmp/port2vlan.conf";
$vlans_assignment = shell_exec("/wr/bin/wrsw_vlans --elist >".$tmp_assign_file);
$vlans_assignment = shell_exec("/wr/bin/wrs_vlans --elist >".$tmp_assign_file);
$vlans_assignment = shell_exec("cat ".$tmp_assign_file." | sed -n '/ /s/ \+/ /gp'");
$vlans_assignment = explode("\n", $vlans_assignment);
......@@ -116,7 +116,7 @@
echo '<br>'.$_POST['mode0'];
//Parse input and run the command
if (!empty($_POST['updatevlan'])){
$vlan_cmd= "/wr/bin/wrsw_vlans ";
$vlan_cmd= "/wr/bin/wrs_vlans ";
for($i = 0; $i < 18; $i++){
//if(strcmp($_POST['vlan'.$i],"disabled")){ //VLAN selected
......@@ -139,7 +139,7 @@
//}
$vlan_cmd= "/wr/bin/wrsw_vlans ";
$vlan_cmd= "/wr/bin/wrs_vlans ";
}
header('Location: vlan.php');
}
......
......@@ -27,7 +27,7 @@
echo '<center><strong>Existing VLANs</strong></center><hr>';
$tmp_vlan_file="/tmp/vlans.conf";
$vlans = shell_exec("/wr/bin/wrsw_vlans --list >".$tmp_vlan_file);
$vlans = shell_exec("/wr/bin/wrs_vlans --list >".$tmp_vlan_file);
$vlans = shell_exec("cat ".$tmp_vlan_file." | sed -n '/ /s/ \+/ /gp'");
$vlans = explode("\n", $vlans);
......@@ -90,7 +90,7 @@
echo '<tr align=center><th><font color="blue">Port</font></strong></th><th><font color="blue">QMode</font></th><th><font color="blue">Priority</font></th><th><font color="blue">VLAN ID</font></th><th><font color="blue">MAC Address</font></th></tr>';
$tmp_vlan_file="/tmp/port2vlan.conf";
$vlans = shell_exec("/wr/bin/wrsw_vlans --elist >".$tmp_vlan_file);
$vlans = shell_exec("/wr/bin/wrs_vlans --elist >".$tmp_vlan_file);
$vlans = shell_exec("cat ".$tmp_vlan_file." | sed -n '/ /s/ \+/ /gp'");
$vlans = explode("\n", $vlans);
......
wrs_pstats
\ No newline at end of file
wrs_version
\ No newline at end of file
wrs_vlans
\ No newline at end of file
......@@ -10,7 +10,7 @@ for arg in $(cat /proc/cmdline); do
done
# Obtain the type of FPGA (LX130XT or LX240XT)
tfpga=$($WR_HOME/bin/wrsw_version -F)
tfpga=$($WR_HOME/bin/wrs_version -F)
$WR_HOME/bin/load-virtex $WR_HOME/lib/firmware/18p_mb-${tfpga}.bin
$WR_HOME/bin/load-lm32 $WR_HOME/lib/firmware/rt_cpu.bin
......
......@@ -402,7 +402,7 @@ portPeer OBJECT-TYPE
::= { ppsiPort 4 }
-- Versions (4) are all just strings, 6 of them
-- Versions (4) are all just strings, several of them
wrsVersionSw OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..64))
......@@ -441,7 +441,7 @@ wrsVersionHw1 OBJECT-TYPE
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The hardware version: PCB"
"The hardware version: minibackplane PCB"
::= { wrsVersion 5 }
wrsVersionHw2 OBJECT-TYPE
......@@ -452,6 +452,30 @@ wrsVersionHw2 OBJECT-TYPE
"The hardware version: FPGA"
::= { wrsVersion 6 }
wrsManufacturer OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..64))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The name of the manufacturing company"
::= { wrsVersion 7 }
wrsSerialNumber OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..32))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The serial number (or string) of the switch"
::= { wrsVersion 8 }
wrsScbVersion OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..32))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The version of the SCB (motherboard)"
::= { wrsVersion 9 }
-- Date (5), to quickly check wr status
wrsDateTAI OBJECT-TYPE
......
......@@ -12,7 +12,7 @@
#include "wrsSnmp.h"
/* Our structure for caching data */
#define VERSION_N_STRINGS 6 /* sw, 3 gw, 2 hw */
#define VERSION_N_STRINGS 9 /* sw, 3 gw, 2 hw, 3 added later */
struct wrs_v_item {
char *key;
......@@ -25,8 +25,11 @@ static struct wrs_v_item wrs_version[] = {
[1] = {"wr_switch_hdl-commit:"},
[2] = {"general-cores-commit:"},
[3] = {"wr-cores-commit:"},
[4] = {"pcb-version:"},
[4] = {"backplane-version:"},
[5] = {"fpga-type:"},
[6] = {"manufacturer:"},
[7] = {"serial-number:"},
[8] = {"scb-version:"},
};
......@@ -65,7 +68,7 @@ static int version_group(netsnmp_mib_handler *handler,
static void wrs_v_init(void)
{
char s[80], key[40], value[40];
FILE *f = popen("/wr/bin/wrsw_version -t", "r");
FILE *f = popen("/wr/bin/wrs_version -t", "r");
int i;
if (!f) {
......
......@@ -7,11 +7,12 @@ wr_phytool
com
mapper
wmapper
wrsw_version
wrs_version
wr_date
fix_tai_offset
wr_management
lm32-vuart
tru_mon
wrsw_pstats
wrsw_vlans
wrs_pstats
wrs_vlans
sdb-read
TOOLS = rtu_stat wr_mon wr_phytool spll_dbg_proxy load-lm32 load-virtex com
TOOLS += mapper wmapper
TOOLS += wrsw_version wr_date wr_management lm32-vuart wrsw_pstats
TOOLS += wrsw_vlans
TOOLS += wrs_version wr_date wr_management lm32-vuart wrs_pstats
TOOLS += wrs_vlans
TOOLS += sdb-read
# # Standard stanza for cross-compilation (courtesy of the linux makefile)
......@@ -27,6 +28,7 @@ CFLAGS = -O2 -g -Wall \
-I../wrsw_hal \
-I../wrsw_rtud \
-I../mini-rpc \
-I../libsdb \
-I../ptp-noposix/PTPWRd \
-I../include
......@@ -37,7 +39,8 @@ endif
LDFLAGS = -L../mini-rpc \
-L../libptpnetif \
-L../libswitchhw \
-lminipc -lptpnetif -lswitchhw -llua -lm -ldl
-L../libsdb \
-lminipc -lptpnetif -lswitchhw -lsdbfs -llua -lm -ldl
all: $(TOOLS)
......@@ -62,11 +65,11 @@ load-virtex: load-virtex.o load-fpga.o
load-lm32: load-lm32.o
${CC} -o $@ $^ $(LDFLAGS)
wrsw_version.o: wrsw_version.c
wrs_version.o: wrs_version.c
${CC} ${CFLAGS} -D__GIT_USR__="\"${GIT_USR}\"" \
-D__GIT_VER__="\"${GIT_VER}\"" $(LDFLAGS) -c -o $@ $^
wrsw_version: wrsw_version.o
wrs_version: wrs_version.o
${CC} -o $@ $^ $(LDFLAGS)
test_rt: test_rt.o ../wrsw_hal/rt_client.o
......@@ -77,13 +80,16 @@ test_ts: test_ts.o ../wrsw_hal/rt_client.o
port_calibrator: port_calibrator.o ../wrsw_hal/rt_client.o
${CC} -o $@ $^ $(LDFLAGS)
wrsw_pstats: wrsw_pstats.o
wrs_pstats: wrs_pstats.o
${CC} -o $@ $^ $(LDFLAGS)
lm32-vuart: lm32-vuart.o
${CC} -o $@ $^ $(LDFLAGS)
wrsw_vlans: wrsw_vlans.o
wrs_vlans: wrs_vlans.o
${CC} -o $@ $^ $(LDFLAGS)
sdb-read: sdb-read.o
${CC} -o $@ $^ $(LDFLAGS)
clean:
......
/*
* Copyright (C) 2012,2014 CERN (www.cern.ch)
* Author: Alessandro Rubini <rubini@gnudd.com>
*
* Released according to the GNU GPL, version 2 or any later version.
*
* This work is part of the White Rabbit project, a research effort led
* by CERN, the European Institute for Nuclear Research.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <getopt.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include "libsdbfs.h"
char *prgname;
int opt_long, opt_verbose, opt_read, opt_entry, opt_mem;
unsigned long opt_memaddr, opt_memsize;
static void help(void)
{
fprintf(stderr, "%s: Use: \"%s [options] <image-file> [<file>]\n",
prgname, prgname);
fprintf(stderr, " -l long listing (like ls -l)\n");
fprintf(stderr, " -v verbose\n");
fprintf(stderr, " -r force use of read(2), not mmap(2)\n");
fprintf(stderr, " -e <num> entry point offset\n");
fprintf(stderr, " -m <size>@<addr> memory subset to use\n");
fprintf(stderr, " -m <addr>+<size> memory subset to use\n");
exit(1);
}
struct sdbr_drvdata {
void *mapaddr;
FILE *f;
unsigned long memaddr;
unsigned long memsize;
};
/*
* This read method is needed for non-mmappable files, or stuff that
* you can't know the size of (e.g., char devices). You can force use of
* read, to exercise the library procedures, using "-r"
*/
static int do_read(struct sdbfs *fs, int offset, void *buf, int count)
{
struct sdbr_drvdata *drvdata = fs->drvdata;
if (opt_verbose)
fprintf(stderr, "%s @ 0x%08x - size 0x%x (%i)\n", __func__,
offset, count, count);
if (drvdata->mapaddr) {
memcpy(buf, drvdata->mapaddr + offset, count);
return count;
}
/* not mmapped: seek and read */
if (fseek(drvdata->f, drvdata->memaddr + offset, SEEK_SET) < 0)
return -1;
return fread(buf, 1, count, drvdata->f);
}
/* Boring ascii representation of a device */
static void list_device(struct sdb_device *d, int depth, int base)
{
struct sdb_product *p;
struct sdb_component *c;
static int warned;
int i;
c = &d->sdb_component;
p = &c->product;
if (!opt_long) {
printf("%.19s\n", p->name);
return;
}
if (!warned) {
fprintf(stderr, "%s: listing format is to be defined\n",
prgname);
warned = 1;
}
/* hack: show directory level looking at the internals */
printf("%016llx:%08x @ %08llx-%08llx ",
ntohll(p->vendor_id), ntohl(p->device_id),
base + ntohll(c->addr_first), base + ntohll(c->addr_last));
for (i = 0; i < depth; i++)
printf(" ");
printf("%.19s\n", p->name);
}
/* The following three function perform the real work, main() is just glue */
static void do_list(struct sdbfs *fs)
{
struct sdb_device *d;
int new = 1;
while ( (d = sdbfs_scan(fs, new)) != NULL) {
list_device(d, fs->depth, fs->base[fs->depth]);
new = 0;
}
}
static void do_cat_name(struct sdbfs *fs, char *name)
{
char buf[4096];
int i;
i = sdbfs_open_name(fs, name);
if (i < 0) {
fprintf(stderr, "%s: %s: %s\n", prgname, name, strerror(-i));
exit(1);
}
while ( (i = sdbfs_fread(fs, -1, buf, sizeof(buf))) > 0)
fwrite(buf, 1, i, stdout);
sdbfs_close(fs);
}
static void do_cat_id(struct sdbfs *fs, uint64_t vendor, uint32_t dev)
{
char buf[4096];
int i;
i = sdbfs_open_id(fs, htonll(vendor), htonl(dev));
if (i < 0) {
fprintf(stderr, "%s: %016llx-%08x: %s\n", prgname, vendor,
dev, strerror(-i));
exit(1);
}
while ( (i = sdbfs_fread(fs, -1, buf, sizeof(buf))) > 0)
fwrite(buf, 1, i, stdout);
sdbfs_close(fs);
}
/* As promised, here's the user-interface glue (and initialization, I admit) */
int main(int argc, char **argv)
{
int c, err;
FILE *f;
struct sdbfs _fs;
struct sdbfs *fs = &_fs; /* I like to type "fs->" */
struct stat stbuf;
struct sdbr_drvdata *drvdata;
void *mapaddr;
char *fsname;
char *filearg = NULL;
unsigned long int32;
unsigned long long int64;
int pagesize = getpagesize();
prgname = argv[0];
while ( (c = getopt(argc, argv, "lvre:m:")) != -1) {
switch (c) {
case 'l':
opt_long = 1;
break;
case 'v':
opt_verbose = 1;
break;
case 'r':
opt_read = 1;
break;
case 'e':
if (sscanf(optarg, "%i", &opt_entry) != 1) {
fprintf(stderr, "%s: not a number \"%s\"\n",
prgname, optarg);
exit(1);
}
break;
case 'm':
/* memory: "size@addr", "addr+size" (blanks ok) */
if (sscanf(optarg, "%li @ %li", &opt_memsize,
&opt_memaddr) == 2)
break;
if (sscanf(optarg, "%li + %li", &opt_memaddr,
&opt_memsize) == 2)
break;
fprintf(stderr, "%s: \"%s\" must be <size>@<addr> "
"or <addr>+<size>\n", prgname, optarg);
exit(1);
break;
}
}
if (optind < argc - 2 || optind > argc - 1)
help();
fsname = argv[optind];
if (optind + 1 < argc)
filearg = argv[optind + 1];
if ( !(f = fopen(fsname, "r")) || fstat(fileno(f), &stbuf) < 0) {
fprintf(stderr, "%s: %s: %s\n", prgname, fsname,
strerror(errno));
exit(1);
}
stbuf.st_size += pagesize - 1;
stbuf.st_size &= ~(pagesize - 1);
mapaddr = mmap(0,
opt_memsize ? opt_memsize : stbuf.st_size,
PROT_READ, MAP_PRIVATE, fileno(f),
opt_memaddr /* 0 by default */);
if (mapaddr == MAP_FAILED)
mapaddr = NULL; /* We'll seek/read */
/* So, describe the filesystem instance and give it to the library */
memset(fs, 0, sizeof(*fs));
drvdata = calloc(1, sizeof(*drvdata));
if (!drvdata) {perror("malloc"); exit(1);}
drvdata->f = f;
drvdata->memaddr = opt_memaddr;
drvdata->memsize = opt_memsize;
drvdata->mapaddr = mapaddr;
fs->drvdata = drvdata;
fs->name = fsname; /* not mandatory */
fs->blocksize = 256; /* only used for writing, actually */
fs->entrypoint = opt_entry;
if (opt_read || !drvdata->mapaddr)
fs->read = do_read;
else
fs->data = mapaddr;
err = sdbfs_dev_create(fs, opt_verbose);
if (err) {
fprintf(stderr, "%s: sdbfs_dev_create(): %s\n", prgname,
strerror(-err));
fprintf(stderr, "\t(wrong entry point 0x%08lx?)\n",
fs->entrypoint);
exit(1);
}
/* Now use the thing: either scan, or look for name, or look for id */
if (!filearg)
do_list(fs);
else if (sscanf(filearg, "%llx:%lx", &int64, &int32) != 2)
do_cat_name(fs, filearg);
else
do_cat_id(fs, int64, int32);
sdbfs_dev_destroy(fs);
return 0;
}
/*
* wrsw_version.c
* wrs_version.c
*
* Obtain the HW version and FPGA type.
*
......@@ -26,7 +26,9 @@
#include <shw_io.h>
#include <hwiu.h>
#include "switch_hw.h"
#include "libsdbfs.h"
#define SDBFS_NAME "/dev/mtd5"
#ifndef __GIT_VER__
#define __GIT_VER__ "x.x"
......@@ -53,6 +55,97 @@ void help(const char* pgrname)
exit(1);
}
/*
* This is the backend of sdb access, using the sdb library. I don't run
* sdb-read because it pretends to mmap the file, and mtd can't be mapped
* (this I'll fix in fpga-config-space); and it would add overhead
*/
struct drvdata {
FILE *f;
};
static struct drvdata drvdata;
static int sdb_read(struct sdbfs *fs, int offset, void *buf, int count)
{
struct drvdata *dd = fs->drvdata;
FILE *f = dd->f;
if (fseek(f, offset, SEEK_SET) < 0)
return -1;
return fread(buf, 1, count, f);
}
static struct sdbfs sdb_instance = {
.drvdata = &drvdata,
.entrypoint = 0, /* unfortunately: to be fixed */
.read = sdb_read,
};
/* This uses the sdb library, with backend above */
static char *sdb_get(char *fname, char *tagname)
{
static char buf[0x420];
static char result[64];
char *unknown = "UNKNOWN";
static FILE *f = (FILE *)-1;
int i, j;
char *s;
if (f == (FILE *)-1) {
f = fopen(SDBFS_NAME, "r");
if (!f) {
fprintf(stderr, "%s: %s\n", SDBFS_NAME,
strerror(errno));
return unknown;
}
drvdata.f = f;
i = sdbfs_dev_create(&sdb_instance, 0 /* verbose */);
if (i != 0) {
printf("Error accessing SDB filesystem in \"%s\"\n",
SDBFS_NAME);
f = NULL;
return unknown;
}
}
if (!f) /* already failed, already reported */
return unknown;
i = sdbfs_open_name(&sdb_instance, fname);
if (i < 0) {
fprintf(stderr, "Can't open \"%s\" in \"%s\"\n",
fname, SDBFS_NAME);
return unknown;
}
i = sdbfs_fread(&sdb_instance, -1, buf, sizeof(buf) - 1);
if (i <= 0)
return unknown;
j = i - 1;
/* trim trailing garbage as the file is assumed to be text */
while (j >= 0 && (buf[j] == 0xff || buf[j] == 0x00))
j--;
if (j >= 0 && buf[j] == '\n')
j--; /* trailing newline too */
buf [j + 1] = '\0';
if (!tagname) {
strncpy(result, buf, sizeof(result));
return result;
}
/* Look for the tag */
s = strstr(buf, tagname);
sscanf(s, "%*[^:]:%*c%[^\n]", result);
return result;
}
static char *get_fpga(void)
{
return sdb_get("hw_info", "fpga");
}
/* Previous stuff follows */
static void print_gw_info(void)
{
struct gw_info info;
......@@ -82,8 +175,11 @@ static void wrsw_tagged_versions(void)
printf("software-version: %s\n", __GIT_VER__); /* see Makefile */
printf("bult-by: %s\n", __GIT_USR__); /* see Makefile */
printf("build-date: %s %s\n", __DATE__, __TIME__);
printf("pcb-version: %s\n", get_shw_info('p'));
printf("fpga-type: %s\n", get_shw_info('f'));
printf("backplane-version: %s\n", get_shw_info('p'));
printf("fpga-type: %s\n", get_fpga());
printf("manufacturer: %s\n", sdb_get("manufacturer", NULL));
printf("serial-number: %s\n", sdb_get("hw_info", "scb_serial"));
printf("scb-version: %s\n", sdb_get("scb_version", NULL));
print_gw_info(); /* This is already tagged */
}
......@@ -114,9 +210,10 @@ int main(int argc, char **argv)
}
func='f';
/* fall through */
case 'p':
case 'f':
/* Warning: this -p and -f is used by the web interface */
case 'f': /* Warning: this -p and -f is used by the web interface */
printf("%s\n", get_fpga());
break;
case 'p': /* Warning: this -p and -f is used by the web interface */
printf("%s\n",get_shw_info(func));
break;
case 'g':
......@@ -135,7 +232,7 @@ int main(int argc, char **argv)
case 'a':
/* Warning: this with "awk '{print $4}'" is ued by the web if */
printf("PCB:%s, FPGA:%s; version: %s (%s); compiled at %s %s\n",
get_shw_info('p'), get_shw_info('f'),
get_shw_info('p'), get_fpga(),
__GIT_VER__, __GIT_USR__, __DATE__, __TIME__);
break;
case 'h':
......
......@@ -32,7 +32,7 @@
#include "switch_hw.h"
#include "fpga_io.h"
#include "wrsw_vlans.h"
#include "wrs_vlans.h"
......
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