Commit 1a18111c authored by Alessandro Rubini's avatar Alessandro Rubini

tool/wrpc-dump: change the access mode, to avoid "gcc -m32"

Accessing data structures in the host to get target fields is broken:
we may have different data size or alignment, or whatever. The hack
of using "-m32" to be able to access lm32 fields from x86-64 is not
clean (we imply the i386 and target have the same size/alignment).
Even worse, not everybody has an x86-64 cross-compiler for i386.

Thus, we use OFFSET_OF in the target, with the lm32 cross compiler,
to build a binary table that is then accessed by the host.

In order to link the data structure in the host we use the assembler
instead of objcopy. With objcopy we'd need to spell out the bfd name
of the host, and we'd get horrible names like
   struct dump_info _binary_dump_info_host_bin_start[];
Signed-off-by: Alessandro Rubini's avatarAlessandro Rubini <rubini@gnudd.com>
parent 9a6a1443
......@@ -24,6 +24,7 @@ obj-$(CONFIG_WR_NODE) += wrc_main.o
obj-$(CONFIG_WR_SWITCH) += wrs_main.o
obj-$(CONFIG_WR_SWITCH) += ipc/minipc-mem-server.o ipc/rt_ipc.o
obj-y += dump-info.o
# our linker script is preprocessed, so have a rule here
%.ld: %.ld.S $(AUTOCONF) .config
$(CC) -include $(AUTOCONF) -E -P $*.ld.S -o $@
......@@ -37,12 +38,15 @@ cflags-$(CONFIG_PPSI) += \
-ffreestanding \
-include include/ppsi-wrappers.h \
-Iinclude \
-I$(PPSI)/include \
-I$(PPSI)/arch-wrpc \
-I$(PPSI)/arch-wrpc/include \
-I$(PPSI)/proto-ext-whiterabbit \
-Iboards/spec
# in order to build tools/wrpc-dump, we need these flags, even for wrs builds
cflags-y += \
-I$(PPSI)/arch-wrpc/include \
-I$(PPSI)/include
obj-ppsi = \
$(PPSI)/ppsi.o
......
#include <sys/types.h>
#include <ppsi/ppsi.h>
#include <softpll_ng.h>
#include "dump-info.h"
struct dump_info dump_info[] = {
/* map for fields of ppsi structures */
#undef DUMP_STRUCT
#define DUMP_STRUCT struct pp_globals
DUMP_HEADER("pp_globals"),
DUMP_FIELD(pointer, pp_instances), /* FIXME: follow this */
DUMP_FIELD(pointer, servo), /* FIXME: follow this */
DUMP_FIELD(pointer, rt_opts),
DUMP_FIELD(pointer, defaultDS),
DUMP_FIELD(pointer, currentDS),
DUMP_FIELD(pointer, parentDS),
DUMP_FIELD(pointer, timePropertiesDS),
DUMP_FIELD(int, ebest_idx),
DUMP_FIELD(int, ebest_updated),
DUMP_FIELD(int, nlinks),
DUMP_FIELD(int, max_links),
//DUMP_FIELD(struct pp_globals_cfg cfg),
DUMP_FIELD(int, rxdrop),
DUMP_FIELD(int, txdrop),
DUMP_FIELD(pointer, arch_data),
DUMP_FIELD(pointer, global_ext_data),
#undef DUMP_STRUCT
#define DUMP_STRUCT DSDefault /* Horrible typedef */
DUMP_HEADER("DSDefault"),
DUMP_FIELD(Boolean, twoStepFlag),
DUMP_FIELD(ClockIdentity, clockIdentity),
DUMP_FIELD(UInteger16, numberPorts),
DUMP_FIELD(ClockQuality, clockQuality),
DUMP_FIELD(UInteger8, priority1),
DUMP_FIELD(UInteger8, priority2),
DUMP_FIELD(UInteger8, domainNumber),
DUMP_FIELD(Boolean, slaveOnly),
#undef DUMP_STRUCT
#define DUMP_STRUCT DSCurrent /* Horrible typedef */
DUMP_HEADER("DSCurrent"),
DUMP_FIELD(UInteger16, stepsRemoved),
DUMP_FIELD(TimeInternal, offsetFromMaster),
DUMP_FIELD(TimeInternal, meanPathDelay), /* oneWayDelay */
DUMP_FIELD(UInteger16, primarySlavePortNumber),
#undef DUMP_STRUCT
#define DUMP_STRUCT DSParent /* Horrible typedef */
DUMP_HEADER("DSParent"),
DUMP_FIELD(PortIdentity, parentPortIdentity),
DUMP_FIELD(UInteger16, observedParentOffsetScaledLogVariance),
DUMP_FIELD(Integer32, observedParentClockPhaseChangeRate),
DUMP_FIELD(ClockIdentity, grandmasterIdentity),
DUMP_FIELD(ClockQuality, grandmasterClockQuality),
DUMP_FIELD(UInteger8, grandmasterPriority1),
DUMP_FIELD(UInteger8, grandmasterPriority2),
#undef DUMP_STRUCT
#define DUMP_STRUCT DSTimeProperties /* Horrible typedef */
DUMP_HEADER("DSTimeProperties"),
DUMP_FIELD(Integer16, currentUtcOffset),
DUMP_FIELD(Boolean, currentUtcOffsetValid),
DUMP_FIELD(Boolean, leap59),
DUMP_FIELD(Boolean, leap61),
DUMP_FIELD(Boolean, timeTraceable),
DUMP_FIELD(Boolean, frequencyTraceable),
DUMP_FIELD(Boolean, ptpTimescale),
DUMP_FIELD(Enumeration8, timeSource),
#undef DUMP_STRUCT
#define DUMP_STRUCT struct wr_servo_state
DUMP_HEADER("servo_state"),
DUMP_FIELD_SIZE(char, if_name, 16),
DUMP_FIELD(unsigned_long, flags),
DUMP_FIELD(int, state),
DUMP_FIELD(Integer32, delta_tx_m),
DUMP_FIELD(Integer32, delta_rx_m),
DUMP_FIELD(Integer32, delta_tx_s),
DUMP_FIELD(Integer32, delta_rx_s),
DUMP_FIELD(Integer32, fiber_fix_alpha),
DUMP_FIELD(Integer32, clock_period_ps),
DUMP_FIELD(TimeInternal, t1),
DUMP_FIELD(TimeInternal, t2),
DUMP_FIELD(TimeInternal, t3),
DUMP_FIELD(TimeInternal, t4),
DUMP_FIELD(Integer32, delta_ms_prev),
DUMP_FIELD(int, missed_iters),
DUMP_FIELD(TimeInternal, mu), /* half of the RTT */
DUMP_FIELD(Integer64, picos_mu),
DUMP_FIELD(Integer32, cur_setpoint),
DUMP_FIELD(Integer32, delta_ms),
DUMP_FIELD(UInteger32, update_count),
DUMP_FIELD(int, tracking_enabled),
DUMP_FIELD_SIZE(char, servo_state_name, 32),
DUMP_FIELD(Integer64, skew),
DUMP_FIELD(Integer64, offset),
DUMP_FIELD(UInteger32, n_err_state),
DUMP_FIELD(UInteger32, n_err_offset),
DUMP_FIELD(UInteger32, n_err_delta_rtt),
#undef DUMP_STRUCT
#define DUMP_STRUCT struct pp_instance
DUMP_HEADER("pp_instance"),
DUMP_FIELD(int, state),
DUMP_FIELD(int, next_state),
DUMP_FIELD(int, next_delay),
DUMP_FIELD(int, is_new_state),
DUMP_FIELD(pointer, arch_data),
DUMP_FIELD(pointer, ext_data),
DUMP_FIELD(unsigned_long, d_flags),
DUMP_FIELD(unsigned_char, flags),
DUMP_FIELD(unsigned_char, role),
DUMP_FIELD(unsigned_char, proto),
DUMP_FIELD(pointer, glbs),
DUMP_FIELD(pointer, n_ops),
DUMP_FIELD(pointer, t_ops),
DUMP_FIELD(pointer, __tx_buffer),
DUMP_FIELD(pointer, __rx_buffer),
DUMP_FIELD(pointer, tx_frame),
DUMP_FIELD(pointer, rx_frame),
DUMP_FIELD(pointer, tx_ptp),
DUMP_FIELD(pointer, rx_ptp),
/* This is a sub-structure */
DUMP_FIELD(int, ch[0].fd),
DUMP_FIELD(pointer, ch[0].custom),
DUMP_FIELD(pointer, ch[0].arch_data),
DUMP_FIELD_SIZE(bina, ch[0].addr, 6),
DUMP_FIELD(int, ch[0].pkt_present),
DUMP_FIELD(int, ch[1].fd),
DUMP_FIELD(pointer, ch[1].custom),
DUMP_FIELD(pointer, ch[1].arch_data),
DUMP_FIELD_SIZE(bina, ch[1].addr, 6),
DUMP_FIELD(int, ch[1].pkt_present),
DUMP_FIELD(ip_address, mcast_addr),
DUMP_FIELD(int, tx_offset),
DUMP_FIELD(int, rx_offset),
DUMP_FIELD_SIZE(bina, peer, 6),
DUMP_FIELD(uint16_t, peer_vid),
DUMP_FIELD(TimeInternal, t1),
DUMP_FIELD(TimeInternal, t2),
DUMP_FIELD(TimeInternal, t3),
DUMP_FIELD(TimeInternal, t4),
DUMP_FIELD(TimeInternal, cField),
DUMP_FIELD(TimeInternal, last_rcv_time),
DUMP_FIELD(TimeInternal, last_snt_time),
DUMP_FIELD(UInteger16, frgn_rec_num),
DUMP_FIELD(Integer16, frgn_rec_best),
//DUMP_FIELD(struct pp_frgn_master frgn_master[PP_NR_FOREIGN_RECORDS]),
DUMP_FIELD(pointer, portDS),
//DUMP_FIELD(unsigned long timeouts[__PP_TO_ARRAY_SIZE]),
DUMP_FIELD(UInteger16, recv_sync_sequence_id),
DUMP_FIELD(Integer8, log_min_delay_req_interval),
//DUMP_FIELD(UInteger16 sent_seq[__PP_NR_MESSAGES_TYPES]),
DUMP_FIELD_SIZE(bina, received_ptp_header, sizeof(MsgHeader)),
//DUMP_FIELD(pointer, iface_name),
//DUMP_FIELD(pointer, port_name),
DUMP_FIELD(int, port_idx),
DUMP_FIELD(int, vlans_array_len),
/* FIXME: array */
DUMP_FIELD(int, nvlans),
/* sub structure */
DUMP_FIELD_SIZE(char, cfg.port_name, 16),
DUMP_FIELD_SIZE(char, cfg.iface_name, 16),
DUMP_FIELD(int, cfg.ext),
DUMP_FIELD(int, cfg.ext),
DUMP_FIELD(unsigned_long, ptp_tx_count),
DUMP_FIELD(unsigned_long, ptp_rx_count),
#undef DUMP_STRUCT
#define DUMP_STRUCT struct softpll_state
DUMP_HEADER("softpll"),
DUMP_FIELD(int, mode),
DUMP_FIELD(int, seq_state),
DUMP_FIELD(int, dac_timeout),
DUMP_FIELD(int, default_dac_main),
DUMP_FIELD(int, delock_count),
DUMP_FIELD(uint32_t, irq_count),
DUMP_FIELD(int, mpll_shift_ps),
DUMP_FIELD(int, helper.p_adder),
DUMP_FIELD(int, helper.p_setpoint),
DUMP_FIELD(int, helper.tag_d0),
DUMP_FIELD(int, helper.ref_src),
DUMP_FIELD(int, helper.sample_n),
DUMP_FIELD(int, helper.delock_count),
/* FIXME: missing helper.pi etc.. */
DUMP_FIELD(int, ext.enabled),
DUMP_FIELD(int, ext.align_state),
DUMP_FIELD(int, ext.align_timer),
DUMP_FIELD(int, ext.align_target),
DUMP_FIELD(int, ext.align_step),
DUMP_FIELD(int, ext.align_shift),
DUMP_FIELD(int, mpll.state),
/* FIXME: mpll.pi etc */
DUMP_FIELD(int, mpll.adder_ref),
DUMP_FIELD(int, mpll.adder_out),
DUMP_FIELD(int, mpll.tag_ref),
DUMP_FIELD(int, mpll.tag_out),
DUMP_FIELD(int, mpll.tag_ref_d),
DUMP_FIELD(int, mpll.tag_out_d),
DUMP_FIELD(uint32_t, mpll.seq_ref),
DUMP_FIELD(int, mpll.seq_out),
DUMP_FIELD(int, mpll.match_state),
DUMP_FIELD(int, mpll.match_seq),
DUMP_FIELD(int, mpll.phase_shift_target),
DUMP_FIELD(int, mpll.phase_shift_current),
DUMP_FIELD(int, mpll.id_ref),
DUMP_FIELD(int, mpll.id_out),
DUMP_FIELD(int, mpll.sample_n),
DUMP_FIELD(int, mpll.delock_count),
DUMP_FIELD(int, mpll.dac_index),
DUMP_FIELD(int, mpll.enabled),
#undef DUMP_STRUCT
#define DUMP_STRUCT struct spll_fifo_log
DUMP_HEADER("pll_fifo"),
DUMP_FIELD(uint32_t, trr),
DUMP_FIELD(uint16_t, irq_count),
DUMP_FIELD(uint16_t, tag_count),
/* FIXME: aux_state and ptracker_state -- variable-len arrays */
DUMP_HEADER("end"),
};
/*
* This header defines structures for dumping other structures from
* binary files. Every arch has a different endianness and alignment/size,
* so we can't just use the structures from the host compiler. It used to
* work for lm32/i386, but it fails with x86-64, so let's change attitude.
*/
#include <stdint.h>
/*
* To ease copying from header files, allow int, char and other known types.
* Please add more type as more structures are included here
*/
enum dump_type {
dump_type_char, /* for zero-terminated strings */
dump_type_bina, /* for binary stull in MAC format */
/* normal types follow */
dump_type_uint32_t,
dump_type_uint16_t,
dump_type_int,
dump_type_unsigned_long,
dump_type_unsigned_char,
dump_type_unsigned_short,
dump_type_double,
dump_type_float,
dump_type_pointer,
/* and strange ones, from IEEE */
dump_type_UInteger64,
dump_type_Integer64,
dump_type_UInteger32,
dump_type_Integer32,
dump_type_UInteger16,
dump_type_Integer16,
dump_type_UInteger8,
dump_type_Integer8,
dump_type_Enumeration8,
dump_type_Boolean,
dump_type_ClockIdentity,
dump_type_PortIdentity,
dump_type_ClockQuality,
/* and this is ours */
dump_type_TimeInternal,
dump_type_ip_address,
};
/* because of the sizeof later on, we need these typedefs */
typedef void * pointer;
typedef unsigned long unsigned_long;
typedef unsigned char unsigned_char;
typedef unsigned short unsigned_short;
typedef struct {unsigned char addr[4];} ip_address;
/*
* This is generated with the target compiler, and then linked
* by the host compiler, so size and alignment must be safe. Then, the
* first structure in each group has the endian flag and the structure name.
* Following ones have zero in endian flag and field name.
*/
#define DUMP_ENDIAN_FLAG 0x12345678
struct dump_info {
uint32_t endian_flag;
uint32_t type;
uint32_t offset;
uint32_t size;
char name[48];
};
extern struct dump_info dump_info[]; /* wrpc-sw/dump-info.c -> bina -> elf */
#define DUMP_HEADER(_struct) { \
.endian_flag = DUMP_ENDIAN_FLAG, \
.name = _struct, \
}
/* The macros below rely on DUMP_STRUCT that must be externally defined */
#define DUMP_FIELD(_type, _fname) { \
.endian_flag = 0, \
.type = dump_type_ ## _type, \
.offset = offsetof(DUMP_STRUCT, _fname),\
.size = sizeof(_type), \
.name = #_fname, \
}
#define DUMP_FIELD_SIZE(_type, _fname, _size) { \
.endian_flag = 0, \
.type = dump_type_ ## _type, \
.offset = offsetof(DUMP_STRUCT, _fname),\
.size = _size, \
.name = #_fname, \
}
......@@ -42,11 +42,20 @@ eb-w1-write: eb-w1-write.c ../dev/w1.c ../dev/w1-eeprom.c eb-w1.c
sdb-wrpc.bin: sdbfs
$(SDBFS)/gensdbfs $< $@
wrpc-dump: wrpc-dump.c
$(CC) -m32 $(CFLAGS) -I../ppsi/include -I../ppsi/arch-wrpc/include \
wrpc-dump: wrpc-dump.c dump-info-host.o
$(CC) $(CFLAGS) -I../ppsi/include -I../ppsi/arch-wrpc/include \
-I ../softpll \
$^ -o $@
dump-info-host.o: ../dump-info.o
$(CROSS_COMPILE)objcopy --only-section=.data.dump_info \
-O binary $^ dump-info-host.bin
$(AS) makebin.S -o $@
../dump-info.o: ../dump-info.c
$(MAKE) -C .. dump-info.o
clean:
rm -f $(ALL) *.o *~
/*
* "objcopy -O binary" they say...
* how can I say "spit the default ELF object format"?
*/
.data
.global dump_info
dump_info:
.incbin "dump-info-host.bin"
......@@ -14,6 +14,7 @@
#include <ppsi/ppsi.h>
#include <softpll_ng.h>
#include <dump-info.h>
/* We have a problem: ppsi is built for wrpc, so it has ntoh[sl] wrong */
#undef ntohl
#undef ntohs
......@@ -22,19 +23,7 @@
#define ntohl(x) __do_not_use
#define ntohll(x) __do_not_use
/* be safe, in case some other header had them slightly differently */
#undef container_of
#undef offsetof
#undef ARRAY_SIZE
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
uint32_t endian_flag; /* from dump_info[0], lazily */
/*
* This picks items from memory, converting as needed. No ntohl any more.
* Next, we'll detect the byte order from the code itself.
......@@ -44,6 +33,11 @@ static long long wrpc_get_64(void *p)
uint64_t *p64 = p;
uint64_t result;
if (endian_flag == DUMP_ENDIAN_FLAG) {
result = *p64 >> 32;
result |= (uint32_t)*p64;
return result;
}
result = __bswap_32((uint32_t)(*p64 >> 32));
result <<= 32;
result |= __bswap_32((uint32_t)*p64);
......@@ -55,6 +49,8 @@ static long wrpc_get_l32(void *p)
{
uint32_t *p32 = p;
if (endian_flag == DUMP_ENDIAN_FLAG)
return *p32;
return __bswap_32(*p32);
}
static int wrpc_get_i32(void *p)
......@@ -66,77 +62,36 @@ static int wrpc_get_16(void *p)
{
uint16_t *p16 = p;
if (endian_flag == DUMP_ENDIAN_FLAG)
return *p16;
return __bswap_16(*p16);
}
/*
* To ease copying from header files, allow int, char and other known types.
* Please add more type as more structures are included here
*/
enum dump_type {
dump_type_char, /* for zero-terminated strings */
dump_type_bina, /* for binary stull in MAC format */
/* normal types follow */
dump_type_uint32_t,
dump_type_uint16_t,
dump_type_int,
dump_type_unsigned_long,
dump_type_unsigned_char,
dump_type_unsigned_short,
dump_type_double,
dump_type_float,
dump_type_pointer,
/* and strange ones, from IEEE */
dump_type_UInteger64,
dump_type_Integer64,
dump_type_UInteger32,
dump_type_Integer32,
dump_type_UInteger16,
dump_type_Integer16,
dump_type_UInteger8,
dump_type_Integer8,
dump_type_Enumeration8,
dump_type_Boolean,
dump_type_ClockIdentity,
dump_type_PortIdentity,
dump_type_ClockQuality,
/* and this is ours */
dump_type_TimeInternal,
dump_type_ip_address,
dump_type_sensor_temp,
};
/*
* A structure to dump fields. This is meant to simplify things, see use here
*/
struct dump_info {
char *name;
enum dump_type type; /* see above */
int offset;
int size; /* only for strings or binary strings */
};
void dump_one_field(void *addr, struct dump_info *info)
{
void *p = addr + info->offset;
void *p = addr + wrpc_get_i32(&info->offset);
struct TimeInternal *ti = p;
struct PortIdentity *pi = p;
struct ClockQuality *cq = p;
char format[16];
int i;
printf(" %-30s ", info->name); /* name includes trailing ':' */
switch(info->type) {
char localname[64];
int i, type, size;
/* now, info may be in wrong-endian. so fix it */
type = wrpc_get_i32(&info->type);
size = wrpc_get_i32(&info->size);
sprintf(localname, "%s:", info->name);
printf(" %-30s ", localname);
switch(type) {
case dump_type_char:
sprintf(format,"\"%%.%is\"\n", info->size);
sprintf(format,"\"%%.%is\"\n", size);
printf(format, (char *)p);
break;
case dump_type_bina:
for (i = 0; i < info->size; i++)
for (i = 0; i < size; i++)
printf("%02x%c", ((unsigned char *)p)[i],
i == info->size - 1 ? '\n' : ':');
i == size - 1 ? '\n' : ':');
break;
case dump_type_UInteger64:
printf("%lld\n", wrpc_get_64(p));
......@@ -174,7 +129,10 @@ void dump_one_field(void *addr, struct dump_info *info)
printf("%f\n", *(float *)p);
break;
case dump_type_pointer:
printf("%08lx\n", wrpc_get_l32(p));
if (size == 4)
printf("%08lx\n", wrpc_get_l32(p));
else
printf("%016llx\n", wrpc_get_64(p));
break;
case dump_type_Integer16:
printf("%i\n", wrpc_get_16(p));
......@@ -211,266 +169,51 @@ void dump_one_field(void *addr, struct dump_info *info)
cq->clockClass, cq->clockAccuracy, cq->clockAccuracy,
wrpc_get_16(&cq->offsetScaledLogVariance));
break;
case dump_type_sensor_temp:
printf("%f\n", ((float)(wrpc_get_i32(p) >> 4)) / 16.0);
break;
}
}
void dump_many_fields(void *addr, struct dump_info *info, int ninfo)
void dump_many_fields(void *addr, char *name)
{
int i;
struct dump_info *p = dump_info;
/* Look for name */
for (; strcmp(p->name, "end"); p++)
if (!strcmp(p->name, name))
break;
if (!addr) {
fprintf(stderr, "dump: pointer not valid\n");
if (!strcmp(p->name, "end")) {
fprintf(stderr, "structure \"%s\" not described\n", name);
return;
}
for (i = 0; i < ninfo; i++)
dump_one_field(addr, info + i);
}
/* the macro below relies on an externally-defined structure type */
#define DUMP_FIELD(_type, _fname) { \
.name = #_fname ":", \
.type = dump_type_ ## _type, \
.offset = offsetof(DUMP_STRUCT, _fname), \
}
#define DUMP_FIELD_SIZE(_type, _fname, _size) { \
.name = #_fname ":", \
.type = dump_type_ ## _type, \
.offset = offsetof(DUMP_STRUCT, _fname), \
.size = _size, \
endian_flag = p->endian_flag;
for (p++; p->endian_flag == 0; p++)
dump_one_field(addr, p);
}
unsigned long wrpc_get_pointer(void *base, char *s_name, char *f_name)
{
struct dump_info *p = dump_info;
int offset;
for (; strcmp(p->name, "end"); p++)
if (!strcmp(p->name, s_name))
break;
if (!strcmp(p->name, "end")) {
fprintf(stderr, "structure \"%s\" not described\n", s_name);
return 0;
}
endian_flag = p->endian_flag;
/* Look for the field: we find the offset, */
for (p++; p->endian_flag == 0; p++) {
if (!strcmp(p->name, f_name)) {
offset = wrpc_get_i32(&p->offset);
return wrpc_get_l32(base + offset);
}
}
fprintf(stderr, "can't find \"%s\" in \"%s\"\n", f_name, s_name);
return 0;
}
/* map for fields of ppsi structures */
#undef DUMP_STRUCT
#define DUMP_STRUCT struct pp_globals
static struct dump_info ppg_info [] = {
DUMP_FIELD(pointer, pp_instances), /* FIXME: follow this */
DUMP_FIELD(pointer, servo), /* FIXME: follow this */
DUMP_FIELD(pointer, rt_opts),
DUMP_FIELD(pointer, defaultDS),
DUMP_FIELD(pointer, currentDS),
DUMP_FIELD(pointer, parentDS),
DUMP_FIELD(pointer, timePropertiesDS),
DUMP_FIELD(int, ebest_idx),
DUMP_FIELD(int, ebest_updated),
DUMP_FIELD(int, nlinks),
DUMP_FIELD(int, max_links),
//DUMP_FIELD(struct pp_globals_cfg cfg),
DUMP_FIELD(int, rxdrop),
DUMP_FIELD(int, txdrop),
DUMP_FIELD(pointer, arch_data),
DUMP_FIELD(pointer, global_ext_data),
};
#undef DUMP_STRUCT
#define DUMP_STRUCT DSDefault /* Horrible typedef */
static struct dump_info dsd_info [] = {
DUMP_FIELD(Boolean, twoStepFlag),
DUMP_FIELD(ClockIdentity, clockIdentity),
DUMP_FIELD(UInteger16, numberPorts),
DUMP_FIELD(ClockQuality, clockQuality),
DUMP_FIELD(UInteger8, priority1),
DUMP_FIELD(UInteger8, priority2),
DUMP_FIELD(UInteger8, domainNumber),
DUMP_FIELD(Boolean, slaveOnly),
};
#undef DUMP_STRUCT
#define DUMP_STRUCT DSCurrent /* Horrible typedef */
static struct dump_info dsc_info [] = {
DUMP_FIELD(UInteger16, stepsRemoved),
DUMP_FIELD(TimeInternal, offsetFromMaster),
DUMP_FIELD(TimeInternal, meanPathDelay), /* oneWayDelay */
DUMP_FIELD(UInteger16, primarySlavePortNumber),
};
#undef DUMP_STRUCT
#define DUMP_STRUCT DSParent /* Horrible typedef */
static struct dump_info dsp_info [] = {
DUMP_FIELD(PortIdentity, parentPortIdentity),
DUMP_FIELD(UInteger16, observedParentOffsetScaledLogVariance),
DUMP_FIELD(Integer32, observedParentClockPhaseChangeRate),
DUMP_FIELD(ClockIdentity, grandmasterIdentity),
DUMP_FIELD(ClockQuality, grandmasterClockQuality),
DUMP_FIELD(UInteger8, grandmasterPriority1),
DUMP_FIELD(UInteger8, grandmasterPriority2),
};
#undef DUMP_STRUCT
#define DUMP_STRUCT DSTimeProperties /* Horrible typedef */
static struct dump_info dstp_info [] = {
DUMP_FIELD(Integer16, currentUtcOffset),
DUMP_FIELD(Boolean, currentUtcOffsetValid),
DUMP_FIELD(Boolean, leap59),
DUMP_FIELD(Boolean, leap61),
DUMP_FIELD(Boolean, timeTraceable),
DUMP_FIELD(Boolean, frequencyTraceable),
DUMP_FIELD(Boolean, ptpTimescale),
DUMP_FIELD(Enumeration8, timeSource),
};
#undef DUMP_STRUCT
#define DUMP_STRUCT struct wr_servo_state
static struct dump_info servo_state_info [] = {
DUMP_FIELD_SIZE(char, if_name, 16),
DUMP_FIELD(unsigned_long, flags),
DUMP_FIELD(int, state),
DUMP_FIELD(Integer32, delta_tx_m),
DUMP_FIELD(Integer32, delta_rx_m),
DUMP_FIELD(Integer32, delta_tx_s),
DUMP_FIELD(Integer32, delta_rx_s),
DUMP_FIELD(Integer32, fiber_fix_alpha),
DUMP_FIELD(Integer32, clock_period_ps),
DUMP_FIELD(TimeInternal, t1),
DUMP_FIELD(TimeInternal, t2),
DUMP_FIELD(TimeInternal, t3),
DUMP_FIELD(TimeInternal, t4),
DUMP_FIELD(Integer32, delta_ms_prev),
DUMP_FIELD(int, missed_iters),
DUMP_FIELD(TimeInternal, mu), /* half of the RTT */
DUMP_FIELD(Integer64, picos_mu),
DUMP_FIELD(Integer32, cur_setpoint),
DUMP_FIELD(Integer32, delta_ms),
DUMP_FIELD(UInteger32, update_count),
DUMP_FIELD(int, tracking_enabled),
DUMP_FIELD_SIZE(char, servo_state_name, 32),
DUMP_FIELD(Integer64, skew),
DUMP_FIELD(Integer64, offset),
DUMP_FIELD(UInteger32, n_err_state),
DUMP_FIELD(UInteger32, n_err_offset),
DUMP_FIELD(UInteger32, n_err_delta_rtt),
};
#undef DUMP_STRUCT
#define DUMP_STRUCT struct pp_instance
static struct dump_info ppi_info [] = {
DUMP_FIELD(int, state),
DUMP_FIELD(int, next_state),
DUMP_FIELD(int, next_delay),
DUMP_FIELD(int, is_new_state),
DUMP_FIELD(pointer, arch_data),
DUMP_FIELD(pointer, ext_data),
DUMP_FIELD(unsigned_long, d_flags),
DUMP_FIELD(unsigned_char, flags),
DUMP_FIELD(unsigned_char, role),
DUMP_FIELD(unsigned_char, proto),
DUMP_FIELD(pointer, glbs),
DUMP_FIELD(pointer, n_ops),
DUMP_FIELD(pointer, t_ops),
DUMP_FIELD(pointer, __tx_buffer),
DUMP_FIELD(pointer, __rx_buffer),
DUMP_FIELD(pointer, tx_frame),
DUMP_FIELD(pointer, rx_frame),
DUMP_FIELD(pointer, tx_ptp),
DUMP_FIELD(pointer, rx_ptp),
/* This is a sub-structure */
DUMP_FIELD(int, ch[0].fd),
DUMP_FIELD(pointer, ch[0].custom),
DUMP_FIELD(pointer, ch[0].arch_data),
DUMP_FIELD_SIZE(bina, ch[0].addr, 6),
DUMP_FIELD(int, ch[0].pkt_present),
DUMP_FIELD(int, ch[1].fd),
DUMP_FIELD(pointer, ch[1].custom),
DUMP_FIELD(pointer, ch[1].arch_data),
DUMP_FIELD_SIZE(bina, ch[1].addr, 6),
DUMP_FIELD(int, ch[1].pkt_present),
DUMP_FIELD(ip_address, mcast_addr),
DUMP_FIELD(int, tx_offset),
DUMP_FIELD(int, rx_offset),
DUMP_FIELD_SIZE(bina, peer, 6),
DUMP_FIELD(uint16_t, peer_vid),
DUMP_FIELD(TimeInternal, t1),
DUMP_FIELD(TimeInternal, t2),
DUMP_FIELD(TimeInternal, t3),
DUMP_FIELD(TimeInternal, t4),
DUMP_FIELD(TimeInternal, cField),
DUMP_FIELD(TimeInternal, last_rcv_time),
DUMP_FIELD(TimeInternal, last_snt_time),
DUMP_FIELD(UInteger16, frgn_rec_num),
DUMP_FIELD(Integer16, frgn_rec_best),
//DUMP_FIELD(struct pp_frgn_master frgn_master[PP_NR_FOREIGN_RECORDS]),
DUMP_FIELD(pointer, portDS),
//DUMP_FIELD(unsigned long timeouts[__PP_TO_ARRAY_SIZE]),
DUMP_FIELD(UInteger16, recv_sync_sequence_id),
DUMP_FIELD(Integer8, log_min_delay_req_interval),
//DUMP_FIELD(UInteger16 sent_seq[__PP_NR_MESSAGES_TYPES]),
DUMP_FIELD_SIZE(bina, received_ptp_header, sizeof(MsgHeader)),
//DUMP_FIELD(pointer, iface_name),
//DUMP_FIELD(pointer, port_name),
DUMP_FIELD(int, port_idx),
DUMP_FIELD(int, vlans_array_len),
/* FIXME: array */
DUMP_FIELD(int, nvlans),
/* sub structure */
DUMP_FIELD_SIZE(char, cfg.port_name, 16),
DUMP_FIELD_SIZE(char, cfg.iface_name, 16),
DUMP_FIELD(int, cfg.ext),
DUMP_FIELD(int, cfg.ext),
DUMP_FIELD(unsigned_long, ptp_tx_count),
DUMP_FIELD(unsigned_long, ptp_rx_count),
};
#undef DUMP_STRUCT
#define DUMP_STRUCT struct softpll_state
static struct dump_info pll_info [] = {
DUMP_FIELD(int, mode),
DUMP_FIELD(int, seq_state),
DUMP_FIELD(int, dac_timeout),
DUMP_FIELD(int, default_dac_main),
DUMP_FIELD(int, delock_count),
DUMP_FIELD(uint32_t, irq_count),
DUMP_FIELD(int, mpll_shift_ps),
DUMP_FIELD(int, helper.p_adder),
DUMP_FIELD(int, helper.p_setpoint),
DUMP_FIELD(int, helper.tag_d0),
DUMP_FIELD(int, helper.ref_src),
DUMP_FIELD(int, helper.sample_n),
DUMP_FIELD(int, helper.delock_count),
/* FIXME: missing helper.pi etc.. */
DUMP_FIELD(int, ext.enabled),
DUMP_FIELD(int, ext.align_state),
DUMP_FIELD(int, ext.align_timer),
DUMP_FIELD(int, ext.align_target),
DUMP_FIELD(int, ext.align_step),
DUMP_FIELD(int, ext.align_shift),
DUMP_FIELD(int, mpll.state),
/* FIXME: mpll.pi etc */
DUMP_FIELD(int, mpll.adder_ref),
DUMP_FIELD(int, mpll.adder_out),
DUMP_FIELD(int, mpll.tag_ref),
DUMP_FIELD(int, mpll.tag_out),
DUMP_FIELD(int, mpll.tag_ref_d),
DUMP_FIELD(int, mpll.tag_out_d),
DUMP_FIELD(uint32_t, mpll.seq_ref),
DUMP_FIELD(int, mpll.seq_out),
DUMP_FIELD(int, mpll.match_state),
DUMP_FIELD(int, mpll.match_seq),
DUMP_FIELD(int, mpll.phase_shift_target),
DUMP_FIELD(int, mpll.phase_shift_current),
DUMP_FIELD(int, mpll.id_ref),
DUMP_FIELD(int, mpll.id_out),
DUMP_FIELD(int, mpll.sample_n),
DUMP_FIELD(int, mpll.delock_count),
DUMP_FIELD(int, mpll.dac_index),
DUMP_FIELD(int, mpll.enabled),
/* FIXME: aux_state and ptracker_state -- variable-len arrays */
};
#undef DUMP_STRUCT
#define DUMP_STRUCT struct spll_fifo_log
static struct dump_info fifo_info [] = {
DUMP_FIELD(uint32_t, trr),
DUMP_FIELD(uint16_t, irq_count),
DUMP_FIELD(uint16_t, tag_count),
};
/* all of these are 0 by default */
unsigned long spll_off, fifo_off, ppi_off, ppg_off, servo_off, ds_off;
......@@ -545,17 +288,15 @@ int main(int argc, char **argv)
/* If we have a new binary file, pick the pointers */
if (!strncmp(mapaddr + 0x80, "WRPC----", 8)) {
struct pp_globals *ppg;
struct pp_instance *ppi;
spll_off = wrpc_get_l32(mapaddr + 0x90);
fifo_off = wrpc_get_l32(mapaddr + 0x94);
ppi_off = wrpc_get_l32(mapaddr + 0x98);
if (ppi_off) { /* This is 0 for wrs */
ppi = mapaddr + ppi_off;
ppg_off = wrpc_get_l32(&ppi->glbs);
ppg = mapaddr + ppg_off;
servo_off = wrpc_get_l32(&ppg->global_ext_data);
ppg_off = wrpc_get_pointer(mapaddr + ppi_off,
"pp_instance", "glbs");
servo_off = wrpc_get_pointer(mapaddr + ppg_off,
"pp_globals", "global_ext_data");
ds_off = ppg_off;
}
}
......@@ -567,8 +308,7 @@ int main(int argc, char **argv)
spll_off = offset;
if (spll_off) {
printf("pll at 0x%lx\n", spll_off);
dump_many_fields(mapaddr + spll_off,
ARRAY_AND_SIZE(pll_info));
dump_many_fields(mapaddr + spll_off, "softpll");
}
if (!strcmp(dumpname, "fifo"))
fifo_off = offset;
......@@ -577,30 +317,25 @@ int main(int argc, char **argv)
printf("fifo log at 0x%lx\n", fifo_off);
for (i = 0; i < FIFO_LOG_LEN; i++)
dump_many_fields(mapaddr + fifo_off
+ i * sizeof(struct spll_fifo_log),
ARRAY_AND_SIZE(fifo_info));
dump_many_fields(mapaddr + fifo_off + i * 8, "pll_fifo");
}
if (!strcmp(dumpname, "ppg"))
ppg_off = offset;
if (ppg_off) {
printf("ppg at 0x%lx\n", ppg_off);
dump_many_fields(mapaddr + ppg_off,
ARRAY_AND_SIZE(ppg_info));
dump_many_fields(mapaddr + ppg_off, "pp_globals");
}
if (!strcmp(dumpname, "ppi"))
ppi_off = offset;
if (ppi_off) {
printf("ppi at 0x%lx\n", ppi_off);
dump_many_fields(mapaddr + ppi_off,
ARRAY_AND_SIZE(ppi_info));
dump_many_fields(mapaddr + ppi_off, "pp_instance");
}
if (!strcmp(dumpname, "servo_state"))
servo_off = offset;
if (servo_off) {
printf("servo_state at 0x%lx\n", servo_off);
dump_many_fields(mapaddr + servo_off,
ARRAY_AND_SIZE(servo_state_info));
dump_many_fields(mapaddr + servo_off, "servo_state");
}
/* This "all" gets the ppg pointer. It's not really all: no pll */
......@@ -608,35 +343,26 @@ int main(int argc, char **argv)
ds_off = offset;
if (ds_off) {
unsigned long newoffset;
struct pp_globals *ppg;
ppg = mapaddr + ds_off;
newoffset = wrpc_get_l32(&ppg->defaultDS);
printf("defaultDS at 0x%lx\n", newoffset);
dump_many_fields(mapaddr + newoffset,
ARRAY_AND_SIZE(dsd_info));
newoffset = wrpc_get_l32(&ppg->currentDS);
printf("currentDS at 0x%lx\n", newoffset);
dump_many_fields(mapaddr + newoffset,
ARRAY_AND_SIZE(dsc_info));
newoffset = wrpc_get_l32(&ppg->parentDS);
printf("parentDS at 0x%lx\n", newoffset);
dump_many_fields(mapaddr + newoffset,
ARRAY_AND_SIZE(dsp_info));
newoffset = wrpc_get_l32(&ppg->timePropertiesDS);
printf("timePropertiesDS at 0x%lx\n", newoffset);
dump_many_fields(mapaddr + newoffset,
ARRAY_AND_SIZE(dstp_info));
newoffset = wrpc_get_l32(&ppg->global_ext_data);
printf("servo_state at 0x%lx\n", newoffset);
dump_many_fields(mapaddr + newoffset,
ARRAY_AND_SIZE(servo_state_info));
ppg_off = ds_off;
newoffset = wrpc_get_pointer(mapaddr + ppg_off,
"pp_globals", "defaultDS");
printf("DSDefault at 0x%lx\n", newoffset);
dump_many_fields(mapaddr + newoffset, "DSDefault");
newoffset = wrpc_get_pointer(mapaddr + ppg_off,
"pp_globals", "currentDS");
printf("DSCurrent at 0x%lx\n", newoffset);
dump_many_fields(mapaddr + newoffset, "DSCurrent");
newoffset = wrpc_get_pointer(mapaddr + ppg_off,
"pp_globals", "parentDS");
dump_many_fields(mapaddr + newoffset, "DSParent");
newoffset = wrpc_get_pointer(mapaddr + ppg_off,
"pp_globals", "timePropertiesDS");
printf("DSTimeProperties at 0x%lx\n", newoffset);
dump_many_fields(mapaddr + newoffset, "DSTimeProperties");
}
......
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