Commit 4972c956 authored by Adam Wujek's avatar Adam Wujek 💬

Merge branch 'adam-ppsi_shm'

parents 2181324a ea68c737
......@@ -53,6 +53,7 @@ static DSCurrent currentDS;
static DSParent parentDS;
static DSTimeProperties timePropertiesDS;
static struct pp_servo servo;
static struct wr_servo_state_t servo_state;
static struct wr_dsport wr_dsport = {
.ops = &wrpc_wr_operations,
......@@ -91,6 +92,7 @@ static struct pp_globals ppg_static = {
.currentDS = &currentDS,
.parentDS = &parentDS,
.timePropertiesDS = &timePropertiesDS,
.global_ext_data = &servo_state,
};
int wrc_ptp_init()
......
......@@ -102,23 +102,26 @@ struct hal_port_state {
uint32_t ep_base;
};
struct hal_temp_sensors {
int fpga; /* IC19 */
int pll; /* IC18 */
int psl; /* IC20 Power Supply Left (PSL) */
int psr; /* IC17 Power Supply Right (PSR) */
int fpga_thold; /* Threshold value for FPGA temperature */
int pll_thold; /* Threshold value for PLL temperature */
int psl_thold; /* Threshold value for PSL temperature */
int psr_thold; /* Threshold value for PSR temperature */
};
/* This is the overall structure stored in shared memory */
#define HAL_SHMEM_VERSION 4 /* Version 4 because of new fields in struct
* hal_port_state */
#define HAL_SHMEM_VERSION 6 /* Version 6 because of new structure
* hal_temp_sensors in hal_shmem_header */
struct hal_shmem_header {
int nports;
struct hal_port_state *ports;
struct hal_temp_sensors temp;
};
/*
* The following functions were in userspace/wrsw_hal/hal_ports.c,
* and are used to marshall data for the RPC format. Now that we
* offer shared memory, it is the caller who must convert data to
* the expected format (which remains the RPC one as I write this).
*/
struct hal_port_state *hal_port_lookup(struct hal_port_state *ports,
const char *name);
static inline int state_up(int state)
{
return (state != HAL_PORT_STATE_LINK_DOWN
......@@ -126,7 +129,8 @@ static inline int state_up(int state)
}
static inline struct hal_port_state *hal_lookup_port(
struct hal_port_state *ports, int nports, char *name)
struct hal_port_state *ports, int nports,
const char *name)
{
int i;
......
......@@ -22,12 +22,13 @@
#define SFP_FLAG_DEVICE_DATA (1 << 1)
struct shw_sfp_caldata {
int flags;
uint32_t flags;
/*
* Part number used to identify it. Serial number because we
* may specify per-specimen delays, but it is not used at this
* point in time
*/
char vendor_name[16];
char part_num[16];
char vendor_serial[16];
/* Callibration data */
......@@ -103,7 +104,8 @@ int shw_sfp_read_db(void);
int shw_sfp_read_verify_header(int num, struct shw_sfp_header *head);
/* return NULL if no data found */
struct shw_sfp_caldata *shw_sfp_get_cal_data(int num);
struct shw_sfp_caldata *shw_sfp_get_cal_data(int num,
struct shw_sfp_header *head);
/* Read and verify the header all at once. returns -1 on failure */
int shw_sfp_read_verify_header(int num, struct shw_sfp_header *head);
......
......@@ -10,7 +10,6 @@
# define BUILT_WITH_WHITERABBIT 0
#endif
#define WRS_PPSI_SHMEM_VERSION 1
/*
* These are the functions provided by the various wrs files
......
......@@ -11,13 +11,14 @@
#include <sys/mman.h>
#include <libwr/shmem.h>
#define SHM_LOCK_TIMEOUT 2
/* Get wrs shared memory */
/* return NULL and set errno on error */
void *wrs_shm_get(enum wrs_shm_name name_id, char *name, unsigned long flags)
{
struct wrs_shm_head *head;
struct stat stbuf;
struct timespec tv1, tv2;
void *map;
char fname[64];
int write_access = flags & WRS_SHM_WRITE;
......@@ -46,11 +47,32 @@ void *wrs_shm_get(enum wrs_shm_name name_id, char *name, unsigned long flags)
MAP_SHARED, fd, 0);
if (map == MAP_FAILED)
return NULL; /* keep errno */
if (!write_access)
return map;
/* Init the fields */
head = map;
if (!write_access) {
/* This is a reader: if locked, wait for a writer */
if (!(flags & WRS_SHM_LOCKED))
return map;
clock_gettime(CLOCK_MONOTONIC, &tv1);
while (1) {
/* Releasing does not mean initial data is in place! */
/* Read data with wrs_shm_seqbegin and
wrs_shm_seqend! */
if (head->pid && kill(head->pid, 0) == 0)
return map;
usleep(10 * 1000);
clock_gettime(CLOCK_MONOTONIC, &tv2);
if (tv2.tv_sec - tv1.tv_sec < SHM_LOCK_TIMEOUT)
continue;
errno = ETIMEDOUT;
return NULL;
}
}
/* Writer: init the fields */
if (head->pid && kill(head->pid, 0) == 0) {
munmap(map, WRS_SHM_MAX_SIZE);
errno = EBUSY;
......@@ -64,10 +86,14 @@ void *wrs_shm_get(enum wrs_shm_name name_id, char *name, unsigned long flags)
head->stamp = 0;
head->data_off = sizeof(*head);
head->data_size = 0;
head->pid = getpid();
if (flags & WRS_SHM_LOCKED)
head->sequence = 1; /* a sort of lock */
else
head->sequence = 0;
head->pid = getpid(); /* getpid() is a memory barrier, too */
head->pidsequence++;
/* version and size are up to the user (or to allocation) */
head->sequence = 0; /* a sort of unlock */
return map;
}
......@@ -119,12 +145,12 @@ void *wrs_shm_follow(void *headptr, void *ptr)
}
/* Before and after writing a chunk of data, act on sequence and stamp */
void wrs_shm_write(void *headptr, int begin)
void wrs_shm_write(void *headptr, int flags)
{
struct wrs_shm_head *head = headptr;
struct timespec tv;
if (!begin) {
if (flags == WRS_SHM_WRITE_END) {
/* At end-of-writing update the timestamp too */
clock_gettime(CLOCK_MONOTONIC, &tv);
head->stamp = tv.tv_sec;
......
......@@ -10,21 +10,11 @@
#include <hal_exports.h>
#include <wr-api.h>
extern ptpdexp_sync_state_t cur_servo_state;
/* minipc Encoding of the supported commands */
#define PTPDEXP_COMMAND_TRACKING 1
#define PTPDEXP_COMMAND_MAN_ADJUST_PHASE 2
static struct minipc_pd __rpcdef_get_sync_state = {
.name = "get_sync_state",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_STRUCT, ptpdexp_sync_state_t),
.args = {
MINIPC_ARG_END,
},
};
static struct minipc_pd __rpcdef_cmd = {
.name = "cmd",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
......@@ -35,15 +25,6 @@ static struct minipc_pd __rpcdef_cmd = {
},
};
/* Fill struct ptpdexp_sync_state_t with current servo state */
static int wrsipc_get_sync_state(ptpdexp_sync_state_t *state)
{
if (!BUILT_WITH_WHITERABBIT)
cur_servo_state.valid = 0; /* unneeded, likely */
memcpy(state, &cur_servo_state, sizeof(*state));
return 0;
}
/* Execute command coming ipc */
static int wrsipc_cmd(int cmd, int value)
{
......@@ -58,19 +39,6 @@ static int wrsipc_cmd(int cmd, int value)
}
/* Two functions to manage packet/args conversions */
static int export_get_sync_state(const struct minipc_pd *pd,
uint32_t *args, void *ret)
{
ptpdexp_sync_state_t state;
wrsipc_get_sync_state(&state);
*(ptpdexp_sync_state_t *)ret = state;
return 0;
}
static int export_cmd(const struct minipc_pd *pd,
uint32_t *args, void *ret)
{
......@@ -83,9 +51,7 @@ static int export_cmd(const struct minipc_pd *pd,
/* To be called at startup, right after the creation of server channel */
void wrs_init_ipcserver(struct minipc_ch *ppsi_ch)
{
__rpcdef_get_sync_state.f = export_get_sync_state;
__rpcdef_cmd.f = export_cmd;
minipc_export(ppsi_ch, &__rpcdef_get_sync_state);
minipc_export(ppsi_ch, &__rpcdef_cmd);
}
......@@ -58,7 +58,7 @@ struct minipc_ch *hal_ch;
struct minipc_ch *ppsi_ch;
struct hal_port_state *hal_ports;
int hal_nports;
struct wrs_shm_head *ppsi_head;
/*
* we need to call calloc, to reset all stuff that used to be static,
* but we'd better have a simple prototype, compatilble with wrs_shm_alloc()
......@@ -80,7 +80,7 @@ int main(int argc, char **argv)
unsigned long seed;
struct timex t;
int i, hal_retries;
struct wrs_shm_head *hal_head, *ppsi_head;
struct wrs_shm_head *hal_head;
struct hal_shmem_header *h;
void *(*alloc_fn)(void *headptr, size_t size) = local_malloc;
......@@ -113,10 +113,24 @@ int main(int argc, char **argv)
"shared memory\n");
exit(1);
}
if (hal_head->version != HAL_SHMEM_VERSION) {
pp_printf("ppsi: unknown HAL's shm version %i "
"(known is %i)\n", hal_head->version,
HAL_SHMEM_VERSION);
exit(1);
}
h = (void *)hal_head + hal_head->data_off;
hal_nports = h->nports;
hal_ports = wrs_shm_follow(hal_head, h->ports);
if (!hal_ports) {
pp_printf("ppsi: unable to follow hal_ports pointer "
"in HAL's shmem\n");
exit(1);
}
/* And create your own channel, until we move to shmem too */
ppsi_ch = minipc_server_create("ptpd", 0);
if (!ppsi_ch) { /* FIXME should we retry ? */
......@@ -125,7 +139,8 @@ int main(int argc, char **argv)
}
wrs_init_ipcserver(ppsi_ch);
ppsi_head = wrs_shm_get(wrs_shm_ptp, "ppsi", WRS_SHM_WRITE);
ppsi_head = wrs_shm_get(wrs_shm_ptp, "ppsi",
WRS_SHM_WRITE | WRS_SHM_LOCKED);
if (!ppsi_head) {
fprintf(stderr, "Fatal: could not create shmem: %s\n",
strerror(errno));
......@@ -145,6 +160,9 @@ int main(int argc, char **argv)
ppg->rt_opts = &__pp_default_rt_opts;
ppg->max_links = PP_MAX_LINKS;
ppg->global_ext_data = alloc_fn(ppsi_head,
sizeof(struct wr_servo_state_t));
/* NOTE: arch_data is not in shmem */
ppg->arch_data = malloc( sizeof(struct unix_arch_data));
ppg->pp_instances = alloc_fn(ppsi_head,
ppg->max_links * sizeof(*ppi));
......@@ -186,7 +204,6 @@ int main(int argc, char **argv)
}
}
for (i = 0; i < ppg->nlinks; i++) {
ppi = INST(ppg, i);
NP(ppi)->ch[PP_NP_EVT].fd = -1;
NP(ppi)->ch[PP_NP_GEN].fd = -1;
......@@ -225,6 +242,10 @@ int main(int argc, char **argv)
seed = atoi(getenv("PPSI_DROP_SEED"));
ppsi_drop_init(ppg, seed);
/* release lock from wrs_shm_get */
if (BUILT_WITH_WHITERABBIT)
wrs_shm_write(ppsi_head, WRS_SHM_WRITE_END);
wrs_main_loop(ppg);
return 0; /* never reached */
}
......@@ -226,6 +226,7 @@ struct pp_globals {
int rxdrop, txdrop; /* fault injection, per thousand */
void *arch_data; /* if arch needs it */
void *global_ext_data; /* if protocol ext needs it */
/* FIXME Here include all is common to many interfaces */
};
......
......@@ -24,14 +24,13 @@ static int wr_init(struct pp_instance *ppi, unsigned char *pkt, int plen)
static int wr_open(struct pp_globals *ppg, struct pp_runtime_opts *rt_opts)
{
static struct wr_data_t wr_data; /* WR-specific global data */
int i;
/* If current arch (e.g. wrpc) is not using the 'pp_links style'
* configuration, just assume there is one ppi instance,
* already configured properly by the arch's main loop */
if (ppg->nlinks == 0) {
INST(ppg, 0)->ext_data = &wr_data;
INST(ppg, 0)->ext_data = ppg->global_ext_data;
return 0;
}
......@@ -40,7 +39,7 @@ static int wr_open(struct pp_globals *ppg, struct pp_runtime_opts *rt_opts)
/* FIXME check if correct: assign to each instance the same
* wr_data. May I move it to pp_globals? */
INST(ppg, i)->ext_data = &wr_data;
INST(ppg, i)->ext_data = ppg->global_ext_data;
if (ppi->cfg.ext == PPSI_EXT_WR) {
switch (ppi->role) {
......
......@@ -12,6 +12,9 @@
#include <ppsi/lib.h>
#include "wr-constants.h"
#define WRS_PPSI_SHMEM_VERSION 3 /* added fields to pp_globals and
wr_servo_state_t */
/*
* This structure is used as extension-specific data in the DSPort
* (see wrspec.v2-06-07-2011, page 17)
......@@ -121,7 +124,7 @@ struct wr_operations {
/* wr_servo interface */
int wr_servo_init(struct pp_instance *ppi);
void wr_servo_reset();
void wr_servo_reset(void);
int wr_servo_man_adjust_phase(int phase);
void wr_servo_enable_tracking(int enable);
int wr_servo_got_sync(struct pp_instance *ppi, TimeInternal *t1,
......@@ -133,9 +136,8 @@ struct wr_servo_state_t {
char if_name[16];
int state;
int next_state;
TimeInternal prev_t4;
TimeInternal mu; /* half of the RTT */
TimeInternal nsec_offset;
int64_t picos_mu;
int32_t delta_tx_m;
int32_t delta_rx_m;
int32_t delta_tx_s;
......@@ -148,27 +150,14 @@ struct wr_servo_state_t {
int32_t fiber_fix_alpha;
int32_t clock_period_ps;
int missed_iters;
};
/* FIXME: what is the difference with the above? */
typedef struct{
int valid;
char slave_servo_state[32];
char sync_source[32];
uint32_t update_count;
int tracking_enabled;
int64_t mu;
int64_t delay_ms;
int64_t delta_tx_m;
int64_t delta_rx_m;
int64_t delta_tx_s;
int64_t delta_rx_s;
int64_t fiber_asymmetry;
int64_t total_asymmetry;
int64_t cur_offset;
int64_t cur_setpoint;
int64_t cur_skew;
int64_t update_count;
} ptpdexp_sync_state_t ;
char servo_state_name[32];
int64_t skew;
int64_t offset;
};
/* All data used as extension ppsi-wr must be put here */
struct wr_data_t {
......
#include <ppsi/ppsi.h>
#include "wr-api.h"
#include <libwr/shmem.h>
#define WR_SERVO_NONE 0
#define WR_SYNC_NSEC 1
......@@ -23,9 +24,11 @@ static const char *servo_name[] = {
[WR_WAIT_OFFSET_STABLE] = "WAIT_OFFSET_STABLE",
};
ptpdexp_sync_state_t cur_servo_state; /* Exported with mini-rpc */
static int tracking_enabled = 1; /* FIXME: why? */
extern struct wrs_shm_head *ppsi_head;
static struct wr_servo_state_t *saved_servo_pointer; /* required for
* wr_servo_reset, which doesn't
* have ppi context. */
void wr_servo_enable_tracking(int enable)
{
......@@ -139,9 +142,10 @@ static TimeInternal ts_hardwarize(TimeInternal ts, int clock_period_ps)
static int got_sync = 0;
void wr_servo_reset()
void wr_servo_reset(void)
{
cur_servo_state.valid = 0;
if (saved_servo_pointer)
saved_servo_pointer->valid = 0;
}
int wr_servo_init(struct pp_instance *ppi)
......@@ -149,7 +153,8 @@ int wr_servo_init(struct pp_instance *ppi)
struct wr_dsport *wrp = WR_DSPOR(ppi);
struct wr_servo_state_t *s =
&((struct wr_data_t *)ppi->ext_data)->servo_state;
/* shmem lock */
wrs_shm_write(ppsi_head, WRS_SHM_WRITE_BEGIN);
/* Determine the alpha coefficient */
if (wrp->ops->read_calib_data(ppi, 0, 0,
&s->fiber_fix_alpha, &s->clock_period_ps) != WR_HW_CALIB_OK)
......@@ -171,22 +176,21 @@ int wr_servo_init(struct pp_instance *ppi)
s->delta_tx_s = ((((int32_t)WR_DSPOR(ppi)->deltaTx.scaledPicoseconds.lsb) >> 16) & 0xffff) | (((int32_t)WR_DSPOR(ppi)->deltaTx.scaledPicoseconds.msb) << 16);
s->delta_rx_s = ((((int32_t)WR_DSPOR(ppi)->deltaRx.scaledPicoseconds.lsb) >> 16) & 0xffff) | (((int32_t)WR_DSPOR(ppi)->deltaRx.scaledPicoseconds.msb) << 16);
cur_servo_state.delta_tx_m = (int64_t)s->delta_tx_m;
cur_servo_state.delta_rx_m = (int64_t)s->delta_rx_m;
cur_servo_state.delta_tx_s = (int64_t)s->delta_tx_s;
cur_servo_state.delta_rx_s = (int64_t)s->delta_rx_s;
/* FIXME: useful?
strncpy(cur_servo_state.sync_source,
clock->netPath.ifaceName, 16);//fixme
*/
strcpy(cur_servo_state.slave_servo_state, "Uninitialized");
strcpy(s->servo_state_name, "Uninitialized");
cur_servo_state.valid = 1;
cur_servo_state.update_count = 0;
saved_servo_pointer = s;
saved_servo_pointer->valid = 1;
s->update_count = 0;
got_sync = 0;
/* shmem unlock */
wrs_shm_write(ppsi_head, WRS_SHM_WRITE_END);
return 0;
}
......@@ -254,9 +258,13 @@ int wr_servo_update(struct pp_instance *ppi)
s->t3.correct, s->t4.correct);
return 0;
}
/* shmem lock */
wrs_shm_write(ppsi_head, WRS_SHM_WRITE_BEGIN);
errcount = 0;
cur_servo_state.update_count++;
s->update_count++;
got_sync = 0;
......@@ -269,29 +277,22 @@ int wr_servo_update(struct pp_instance *ppi)
}
s->mu = ts_sub(ts_sub(s->t4, s->t1), ts_sub(s->t3, s->t2));
s->picos_mu = ts_to_picos(s->mu);
big_delta_fix = s->delta_tx_m + s->delta_tx_s
+ s->delta_rx_m + s->delta_rx_s;
delay_ms_fix = (((int64_t)(ts_to_picos(s->mu) - big_delta_fix) * (int64_t) s->fiber_fix_alpha) >> FIX_ALPHA_FRACBITS)
+ ((ts_to_picos(s->mu) - big_delta_fix) >> 1)
delay_ms_fix = (((int64_t)(s->picos_mu - big_delta_fix) * (int64_t) s->fiber_fix_alpha) >> FIX_ALPHA_FRACBITS)
+ ((s->picos_mu - big_delta_fix) >> 1)
+ s->delta_tx_m + s->delta_rx_s + ph_adjust;
ts_offset = ts_add(ts_sub(s->t1, s->t2), picos_to_ts(delay_ms_fix));
ts_offset_hw = ts_hardwarize(ts_offset, s->clock_period_ps);
cur_servo_state.mu = (uint64_t)ts_to_picos(s->mu);
cur_servo_state.cur_offset = ts_to_picos(ts_offset);
/* is it possible to calculate it in client,
* but then t1 and t2 require shmem locks */
s->offset = ts_to_picos(ts_offset);
cur_servo_state.delay_ms = delay_ms_fix;
cur_servo_state.total_asymmetry =
(cur_servo_state.mu - 2LL * (int64_t)delay_ms_fix);
cur_servo_state.fiber_asymmetry =
cur_servo_state.total_asymmetry
- (s->delta_tx_m + s->delta_rx_s)
+ (s->delta_rx_m + s->delta_tx_s);
cur_servo_state.tracking_enabled = tracking_enabled;
s->tracking_enabled = tracking_enabled;
s->delta_ms = delay_ms_fix;
......@@ -316,8 +317,6 @@ int wr_servo_update(struct pp_instance *ppi)
pp_diag(ppi, servo, 2, "offset_hw: %li.%09li\n",
(long)ts_offset_hw.seconds, (long)ts_offset_hw.nanoseconds);
/* The string (the whole cur_servo_state) is exported to wr_mon */
strcpy(cur_servo_state.slave_servo_state, servo_name[s->state]);
pp_diag(ppi, servo, 1, "wr_servo state: %s %s\n",
servo_name[s->state], s->state == WR_WAIT_SYNC_IDLE ?
servo_name[s->next_state] : "");
......@@ -379,8 +378,7 @@ int wr_servo_update(struct pp_instance *ppi)
break;
case WR_TRACK_PHASE:
cur_servo_state.cur_setpoint = s->cur_setpoint;
cur_servo_state.cur_skew = s->delta_ms - s->delta_ms_prev;
s->skew = s->delta_ms - s->delta_ms_prev;
if (ts_offset_hw.seconds !=0 || ts_offset_hw.nanoseconds != 0)
s->state = WR_SYNC_TAI;
......@@ -401,5 +399,10 @@ int wr_servo_update(struct pp_instance *ppi)
break;
}
/* update string state name */
strcpy(s->servo_state_name, servo_name[s->state]);
/* shmem unlock */
wrs_shm_write(ppsi_head, WRS_SHM_WRITE_END);
return 0;
}
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