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();