diff --git a/patches/barebox/v2014.04/0011-lib-sdb-and-sdb.h-from-fpga-config-space-sdbfs-commi.patch b/patches/barebox/v2014.04/0011-lib-sdb-and-sdb.h-from-fpga-config-space-sdbfs-commi.patch
new file mode 100644
index 0000000000000000000000000000000000000000..dd70d9ff70085bd1b9185045b3029c866a6180d5
--- /dev/null
+++ b/patches/barebox/v2014.04/0011-lib-sdb-and-sdb.h-from-fpga-config-space-sdbfs-commi.patch
@@ -0,0 +1,827 @@
+From 5a35bbb8b324be0fe2b40113c26e1c1d9ca1374b Mon Sep 17 00:00:00 2001
+From: Alessandro Rubini <rubini@gnudd.com>
+Date: Mon, 15 Sep 2014 09:54:24 +0200
+Subject: [PATCH 11/13] lib/sdb and sdb.h: from fpga-config-space/sdbfs,
+ commit 17445a2
+
+Signed-off-by: Alessandro Rubini <rubini@gnudd.com>
+---
+ include/sdb.h                   |  159 ++++++++++++++++++++++++++
+ lib/sdb/Makefile                |   43 +++++++
+ lib/sdb/Makefile.arch           |   58 ++++++++++
+ lib/sdb/access.c                |   60 ++++++++++
+ lib/sdb/check-endian            |   24 ++++
+ lib/sdb/glue.c                  |  234 +++++++++++++++++++++++++++++++++++++++
+ lib/sdb/libsdbfs-freestanding.h |   19 ++++
+ lib/sdb/libsdbfs-kernel.h       |   35 ++++++
+ lib/sdb/libsdbfs-user.h         |   15 +++
+ lib/sdb/libsdbfs.h              |   87 +++++++++++++++
+ 10 files changed, 734 insertions(+)
+ create mode 100644 include/sdb.h
+ create mode 100644 lib/sdb/Makefile
+ create mode 100644 lib/sdb/Makefile.arch
+ create mode 100644 lib/sdb/access.c
+ create mode 100755 lib/sdb/check-endian
+ create mode 100644 lib/sdb/glue.c
+ create mode 100644 lib/sdb/libsdbfs-freestanding.h
+ create mode 100644 lib/sdb/libsdbfs-kernel.h
+ create mode 100644 lib/sdb/libsdbfs-user.h
+ create mode 100644 lib/sdb/libsdbfs.h
+
+diff --git a/include/sdb.h b/include/sdb.h
+new file mode 100644
+index 0000000..fbb76a4
+--- /dev/null
++++ b/include/sdb.h
+@@ -0,0 +1,159 @@
++/*
++ * 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__ */
+diff --git a/lib/sdb/Makefile b/lib/sdb/Makefile
+new file mode 100644
+index 0000000..4699673
+--- /dev/null
++++ b/lib/sdb/Makefile
+@@ -0,0 +1,43 @@
++
++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:
+diff --git a/lib/sdb/Makefile.arch b/lib/sdb/Makefile.arch
+new file mode 100644
+index 0000000..12ca01c
+--- /dev/null
++++ b/lib/sdb/Makefile.arch
+@@ -0,0 +1,58 @@
++
++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
+diff --git a/lib/sdb/access.c b/lib/sdb/access.c
+new file mode 100644
+index 0000000..93b5696
+--- /dev/null
++++ b/lib/sdb/access.c
+@@ -0,0 +1,60 @@
++/*
++ * 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;
++}
+diff --git a/lib/sdb/check-endian b/lib/sdb/check-endian
+new file mode 100755
+index 0000000..0c2acff
+--- /dev/null
++++ b/lib/sdb/check-endian
+@@ -0,0 +1,24 @@
++#!/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
+diff --git a/lib/sdb/glue.c b/lib/sdb/glue.c
+new file mode 100644
+index 0000000..d8ef3cf
+--- /dev/null
++++ b/lib/sdb/glue.c
+@@ -0,0 +1,234 @@
++/*
++ * 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;
++}
++
+diff --git a/lib/sdb/libsdbfs-freestanding.h b/lib/sdb/libsdbfs-freestanding.h
+new file mode 100644
+index 0000000..3f7868d
+--- /dev/null
++++ b/lib/sdb/libsdbfs-freestanding.h
+@@ -0,0 +1,19 @@
++
++/* 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
+diff --git a/lib/sdb/libsdbfs-kernel.h b/lib/sdb/libsdbfs-kernel.h
+new file mode 100644
+index 0000000..5f545e8
+--- /dev/null
++++ b/lib/sdb/libsdbfs-kernel.h
+@@ -0,0 +1,35 @@
++/*
++ * 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__)
+diff --git a/lib/sdb/libsdbfs-user.h b/lib/sdb/libsdbfs-user.h
+new file mode 100644
+index 0000000..d54961c
+--- /dev/null
++++ b/lib/sdb/libsdbfs-user.h
+@@ -0,0 +1,15 @@
++#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__ */
+diff --git a/lib/sdb/libsdbfs.h b/lib/sdb/libsdbfs.h
+new file mode 100644
+index 0000000..15325be
+--- /dev/null
++++ b/lib/sdb/libsdbfs.h
+@@ -0,0 +1,87 @@
++#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__ */
+-- 
+1.7.10.4
+
diff --git a/patches/barebox/v2014.04/0012-lib-sdb-bb-fixes-to-be-ported-in-fpga-config-space.patch b/patches/barebox/v2014.04/0012-lib-sdb-bb-fixes-to-be-ported-in-fpga-config-space.patch
new file mode 100644
index 0000000000000000000000000000000000000000..1167b7dcace0a61405b6098690fb5a59bf531848
--- /dev/null
+++ b/patches/barebox/v2014.04/0012-lib-sdb-bb-fixes-to-be-ported-in-fpga-config-space.patch
@@ -0,0 +1,41 @@
+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
+
diff --git a/patches/barebox/v2014.04/0012-libsdb-integrate-in-build-system.patch b/patches/barebox/v2014.04/0012-libsdb-integrate-in-build-system.patch
new file mode 100644
index 0000000000000000000000000000000000000000..9fc44d1c4e8ce7cf1516638a58261e04c3f8ffad
--- /dev/null
+++ b/patches/barebox/v2014.04/0012-libsdb-integrate-in-build-system.patch
@@ -0,0 +1,87 @@
+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
+
diff --git a/patches/barebox/v2014.04/0013-commands-add-sdb-commands-to-list-read-setvar.patch b/patches/barebox/v2014.04/0013-commands-add-sdb-commands-to-list-read-setvar.patch
new file mode 100644
index 0000000000000000000000000000000000000000..1c063f4db8f2062d92dc9a0d0755aa22daafcdd9
--- /dev/null
+++ b/patches/barebox/v2014.04/0013-commands-add-sdb-commands-to-list-read-setvar.patch
@@ -0,0 +1,244 @@
+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
+
diff --git a/patches/barebox/v2014.04/0013-libsdb-integrate-in-build-system.patch b/patches/barebox/v2014.04/0013-libsdb-integrate-in-build-system.patch
new file mode 100644
index 0000000000000000000000000000000000000000..98dab817b3040b0f0e78a6d3a3838e1384287591
--- /dev/null
+++ b/patches/barebox/v2014.04/0013-libsdb-integrate-in-build-system.patch
@@ -0,0 +1,87 @@
+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
+
diff --git a/patches/barebox/v2014.04/0014-commands-add-sdb-commands-to-list-read-setvar.patch b/patches/barebox/v2014.04/0014-commands-add-sdb-commands-to-list-read-setvar.patch
new file mode 100644
index 0000000000000000000000000000000000000000..eb695947c530fee1264708f718b793cbbfdfbe36
--- /dev/null
+++ b/patches/barebox/v2014.04/0014-commands-add-sdb-commands-to-list-read-setvar.patch
@@ -0,0 +1,272 @@
+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
+