diff --git a/dev/dev.mk b/dev/dev.mk
index 3d1610d0b553a68fbfb6d0929d01017cf416dee2..1bdf2620fa7f669dc22839f19378ecc24402047f 100644
--- a/dev/dev.mk
+++ b/dev/dev.mk
@@ -7,4 +7,5 @@ OBJS_DEV = 	dev/eeprom.o \
 						dev/syscon.o \
 						dev/uart.o \
 						dev/sfp.o \
-						dev/persistent_mac.o
+						dev/persistent_mac.o \
+						dev/sdb.o
diff --git a/dev/endpoint.c b/dev/endpoint.c
index 0d1693cd0bc31ab1e036f4d87e8a68a4430d59e6..d2c2233f95b61f3141cedccdfe8135d6d3b985a5 100644
--- a/dev/endpoint.c
+++ b/dev/endpoint.c
@@ -27,7 +27,7 @@ LGPL 2.1
 #define DMTD_AVG_SAMPLES 256
 
 static int autoneg_enabled;
-static volatile struct EP_WB *EP = (volatile struct EP_WB *) BASE_EP;
+volatile struct EP_WB *EP;
 
 /* functions for accessing PCS (MDIO) registers */
 uint16_t pcs_read(int location)
@@ -72,6 +72,7 @@ void get_mac_addr(uint8_t dev_addr[])
 /* Initializes the endpoint and sets its local MAC address */
 void ep_init(uint8_t mac_addr[])
 {
+    EP = (volatile struct EP_WB *) BASE_EP;
     set_mac_addr(mac_addr);
 
     *(unsigned int *)(0x62000) = 0x2; // reset network stuff (cleanup required!)
diff --git a/dev/ep_pfilter.c b/dev/ep_pfilter.c
index a71b731b8c70bed93fa76be1378464ff4d70b8ba..adb7f5b4d74ab677be0f301e933f55196743bd5f 100644
--- a/dev/ep_pfilter.c
+++ b/dev/ep_pfilter.c
@@ -81,7 +81,7 @@
 
 #define pfilter_dbg 
 
-static volatile struct EP_WB *EP = (volatile struct EP_WB *) BASE_EP;
+extern volatile struct EP_WB *EP;
 
 static const uint64_t PF_MODE_LOGIC    = (1ULL<<34);
 static const uint64_t PF_MODE_CMP    = 0ULL;
diff --git a/dev/sdb.c b/dev/sdb.c
new file mode 100644
index 0000000000000000000000000000000000000000..794a568c2f420d438c02681940471f144a44b254
--- /dev/null
+++ b/dev/sdb.c
@@ -0,0 +1,129 @@
+#include "hw/memlayout.h"
+
+#define SDB_INTERCONNET 0x00
+#define SDB_DEVICE      0x01
+#define SDB_BRIDGE      0x02
+#define SDB_EMPTY       0xFF
+
+typedef struct pair64 {
+  uint32_t high;
+  uint32_t low;
+} pair64_t;
+
+struct sdb_empty {
+  int8_t reserved[63];
+  uint8_t record_type;
+};
+
+struct sdb_product {
+  pair64_t vendor_id;
+  uint32_t device_id;
+  uint32_t version;
+  uint32_t date;
+  int8_t   name[19];
+  uint8_t  record_type;
+};
+
+struct sdb_component {
+  pair64_t addr_first;
+  pair64_t addr_last;
+  struct sdb_product product;
+};
+
+struct sdb_device {
+  uint16_t abi_class;
+  uint8_t  abi_ver_major;
+  uint8_t  abi_ver_minor;
+  uint32_t bus_specific;
+  struct sdb_component sdb_component;
+};
+
+struct sdb_bridge {
+  pair64_t sdb_child;
+  struct sdb_component sdb_component;
+};
+
+struct sdb_interconnect {
+  uint32_t sdb_magic;
+  uint16_t sdb_records;
+  uint8_t  sdb_version;
+  uint8_t  sdb_bus_type;
+  struct sdb_component sdb_component;
+};
+
+typedef union sdb_record {
+  struct sdb_empty        empty;
+  struct sdb_device       device;
+  struct sdb_bridge       bridge;
+  struct sdb_interconnect interconnect;
+} sdb_record_t;
+
+static unsigned char* find_device_deep(unsigned int base, unsigned int sdb, unsigned int devid) {
+  sdb_record_t* record = (sdb_record_t*)sdb;
+  int records = record->interconnect.sdb_records;
+  int i;
+  
+  for (i = 0; i < records; ++i, ++record) {
+    if (record->empty.record_type == SDB_BRIDGE) {
+      unsigned char* out = 
+        find_device_deep(
+          base + record->bridge.sdb_component.addr_first.low,
+          record->bridge.sdb_child.low,
+          devid);
+      if (out) return out;
+    }
+    if (record->empty.record_type == SDB_DEVICE && 
+        record->device.sdb_component.product.device_id == devid) {
+      break;
+    }
+  }
+  
+  if (i == records) return 0;
+  return (unsigned char*)(base + record->device.sdb_component.addr_first.low);
+}
+
+static void print_devices_deep(unsigned int base, unsigned int sdb) {
+  sdb_record_t* record = (sdb_record_t*)sdb;
+  int records = record->interconnect.sdb_records;
+  int i;
+  char buf[20];
+  
+  for (i = 0; i < records; ++i, ++record) {
+    if (record->empty.record_type == SDB_BRIDGE)
+      print_devices_deep(
+        base + record->bridge.sdb_component.addr_first.low,
+        record->bridge.sdb_child.low);
+    
+    if (record->empty.record_type != SDB_DEVICE) continue;
+    
+    memcpy(buf, record->device.sdb_component.product.name, 19);
+    buf[19] = 0;
+    mprintf("%8x:%8x 0x%8x %s\n", 
+            record->device.sdb_component.product.vendor_id.low,
+            record->device.sdb_component.product.device_id, 
+            base + record->device.sdb_component.addr_first.low,
+            buf);
+  }
+}
+
+static unsigned char* find_device(unsigned int devid) {
+  find_device_deep(0, SDB_ADDRESS, devid);
+}
+
+void sdb_print_devices(void) {
+  mprintf("SDB memory map:\n");
+  print_devices_deep(0, SDB_ADDRESS);
+  mprintf("---\n");
+}
+
+void sdb_find_devices(void) {
+  BASE_MINIC         = find_device(0xab28633a);
+  BASE_EP            = find_device(0x650c2d4f);
+  BASE_SOFTPLL       = find_device(0x65158dc0);
+  BASE_PPS_GEN       = find_device(0xde0d8ced);
+  BASE_SYSCON        = find_device(0xff07fc47);
+  BASE_UART          = find_device(0xe2d13d04);
+  BASE_ONEWIRE       = find_device(0x779c5443);
+  
+  BASE_ETHERBONE_CFG = (unsigned char*)0x20700; /* !!! fixme -- needs HW change */
+}
diff --git a/dev/syscon.c b/dev/syscon.c
index 9afe661664fd6b51ede9b5b278bf23d665ca691f..5572f601a76e8c2effaa5b5c02dfef4cd712c7e0 100644
--- a/dev/syscon.c
+++ b/dev/syscon.c
@@ -3,11 +3,15 @@
 struct s_i2c_if i2c_if[2] = { {SYSC_GPSR_FMC_SCL, SYSC_GPSR_FMC_SDA}, 
                               {SYSC_GPSR_SFP_SCL, SYSC_GPSR_SFP_SDA} };
 
+volatile struct SYSCON_WB *syscon;
+
 /****************************
  *        TIMER
  ***************************/
 void timer_init(uint32_t enable)
 {
+  syscon = (volatile struct SYSCON_WB *) BASE_SYSCON;
+  
   if(enable)
     syscon->TCR |= SYSC_TCR_ENABLE; 
   else
diff --git a/dev/uart.c b/dev/uart.c
index b4606122e4bc1c59b001210e17a30c38292a515c..55ea2bd36d248a1fd7578191d3ba00d98bb29a81 100644
--- a/dev/uart.c
+++ b/dev/uart.c
@@ -9,10 +9,11 @@
     ( ((( (unsigned long long)baudrate * 8ULL) << (16 - 7)) + \
       (CPU_CLOCK >> 8)) / (CPU_CLOCK >> 7) )
 
-static volatile struct UART_WB *uart = (volatile struct UART_WB *) BASE_UART;
+volatile struct UART_WB *uart;
 
 void uart_init()
 {
+	uart = (volatile struct UART_WB *) BASE_UART;
 	uart->BCR = CALC_BAUD(UART_BAUDRATE);
 }
 
diff --git a/include/hw/memlayout.h b/include/hw/memlayout.h
index 53049d6fa276e94ec45651542c010aaa0da80087..34a58b449c8e1c51214b8238ddf1ac5a9e07f232 100644
--- a/include/hw/memlayout.h
+++ b/include/hw/memlayout.h
@@ -1,16 +1,20 @@
 #ifndef __REGS_H
 #define __REGS_H
 
-#define BASE_MINIC    0x20000
-#define BASE_EP   	  0x20100 
-#define BASE_SOFTPLL  0x20200 
-#define BASE_PPS_GEN  0x20300
-#define BASE_SYSCON   0x20400
-#define BASE_UART 	  0x20500
-#define BASE_ONEWIRE  0x20600
-#define BASE_ETHERBONE_CFG 0x20700
+#define SDB_ADDRESS 0x30000
+
+unsigned char* BASE_MINIC;
+unsigned char* BASE_EP;
+unsigned char* BASE_SOFTPLL;
+unsigned char* BASE_PPS_GEN;
+unsigned char* BASE_SYSCON;
+unsigned char* BASE_UART;
+unsigned char* BASE_ONEWIRE;
+unsigned char* BASE_ETHERBONE_CFG;
 
 #define FMC_EEPROM_ADR 0x50
 
+void sdb_find_devices(void);
+void sdb_print_devices(void);
  
 #endif
diff --git a/include/syscon.h b/include/syscon.h
index d8c0448a5753ebbc0afee137f96656882f43652f..dc2d8b2fb18a2efe557b84e6a639b90df465e3a1 100644
--- a/include/syscon.h
+++ b/include/syscon.h
@@ -38,7 +38,7 @@ void timer_init(uint32_t enable);
 uint32_t timer_get_tics();
 void timer_delay(uint32_t how_long);
 
-static volatile struct SYSCON_WB *syscon = (volatile struct SYSCON_WB *) BASE_SYSCON;
+extern volatile struct SYSCON_WB *syscon;
 
 /****************************
  *        GPIO
diff --git a/shell/cmd_sdb.c b/shell/cmd_sdb.c
new file mode 100644
index 0000000000000000000000000000000000000000..3ae4be79d1caf9a1f9791453cb834b65762604e7
--- /dev/null
+++ b/shell/cmd_sdb.c
@@ -0,0 +1,11 @@
+#include "shell.h"
+#include "syscon.h"
+#include "hw/memlayout.h"
+
+extern const char *build_revision, *build_date;
+
+int cmd_sdb(const char *args[])
+{
+	sdb_print_devices();
+	return 0;
+}
\ No newline at end of file
diff --git a/shell/shell.c b/shell/shell.c
index c0470a74519a3bbcddc7210eaca2b4899f706df3..57a300cfdcecba3af78cf5ce15e83c25e207fb96 100644
--- a/shell/shell.c
+++ b/shell/shell.c
@@ -49,6 +49,7 @@ static const struct shell_cmd cmds_list[] = {
 		{ "ip",							cmd_ip },
 #endif
 		{ "mac",						cmd_mac },
+		{ "sdb",						cmd_sdb },
 	
 		{ NULL,			NULL }
 	};
diff --git a/shell/shell.h b/shell/shell.h
index c1e2ba5bde861676ca1de65a6d26097d59a1f9a3..47b468401714b4aa39e9fdca60d5d7afa21cf60f 100644
--- a/shell/shell.h
+++ b/shell/shell.h
@@ -15,6 +15,7 @@ int cmd_mode(const char *args[]);
 int cmd_measure_t24p(const char *args[]);
 int cmd_time(const char *args[]);
 int cmd_ip(const char *args[]);
+int cmd_sdb(const char *args[]);
 int cmd_mac(const char *args[]);
 
 int cmd_env(const char *args[]);
diff --git a/shell/shell.mk b/shell/shell.mk
index 057142dbc6546c21e1d4dbb1d13ba280ac3687ef..cd67fb5051201696d5db3368c7f9e2981eaa7426 100644
--- a/shell/shell.mk
+++ b/shell/shell.mk
@@ -9,6 +9,7 @@ OBJS_SHELL = 	shell/shell.o \
 							shell/cmd_measure_t24p.o \
 							shell/cmd_time.o \
 							shell/cmd_gui.o \
+							shell/cmd_sdb.o \
 							shell/cmd_mac.o
 
 ifneq ($(WITH_ETHERBONE), 0)
diff --git a/softpll/softpll_ng.c b/softpll/softpll_ng.c
index 3d8df71b312b5d8f663442da989a7c4cc9eb418b..eab47b830a86072713f75d9d57edd94badd65fee 100644
--- a/softpll/softpll_ng.c
+++ b/softpll/softpll_ng.c
@@ -13,8 +13,8 @@
 
 volatile int irq_count = 0;
 
-static volatile struct SPLL_WB *SPLL = (volatile struct SPLL_WB *) BASE_SOFTPLL;
-static volatile struct PPSG_WB *PPSG = (volatile struct PPSG_WB *) BASE_PPS_GEN;
+static volatile struct SPLL_WB *SPLL;
+static volatile struct PPSG_WB *PPSG;
 
 #define TRACE(...) TRACE_DEV(__VA_ARGS__)
 
@@ -233,6 +233,9 @@ void spll_init(int mode, int slave_ref_channel, int align_pps)
 	char mode_str[20];
 	volatile int dummy;
 	int i;
+	
+	SPLL = (volatile struct SPLL_WB *) BASE_SOFTPLL;
+	PPSG = (volatile struct PPSG_WB *) BASE_PPS_GEN;
 
 	disable_irq();
 
diff --git a/wrc_main.c b/wrc_main.c
index d6b9b75da9473ee9abea340010d6c2a095abecf3..e7bd9bd4a9060eb7551ee90ce67560891eef428a 100644
--- a/wrc_main.c
+++ b/wrc_main.c
@@ -34,9 +34,12 @@ void wrc_initialize()
   int ret, i;
   uint8_t mac_addr[6], ds18_id[8] = {0,0,0,0,0,0,0,0};
   char sfp_pn[17];
-	
+  
+  sdb_find_devices();
   uart_init();
+  
   mprintf("WR Core: starting up...\n");
+  
   timer_init(1);
   owInit();