/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <signal.h>
#include <limits.h>
#include <time.h>
#include <fmd_time.h>
#include <fmd_alloc.h>
#include <fmd_error.h>
#include <fmd_subr.h>
#include <fmd.h>
void
{
fmd_panic("failed to read time-of-day clock");
}
fmd_time_gethrtime(void)
{
}
void
{
}
void
{
}
void
{
}
/*
* To synchronize TOD with a gethrtime() source, we repeatedly sample TOD in
* between two calls to gethrtime(), which places a reasonably tight bound on
* the high-resolution time that matches the TOD value we sampled. We repeat
* this process several times and ultimately select the sample where the two
* values of gethrtime() were closest. We then assign the average of those
* two high-resolution times to be the gethrtime() associated with that TOD.
*/
void
{
uint_t i;
for (i = 0; i < samples; i++) {
}
}
}
}
/*
* Convert a high-resolution timestamp into 64-bit seconds and nanoseconds.
* For efficiency, the multiplication and division are expanded using the
* clever algorithm originally designed for the kernel in hrt2ts(). Refer to
*/
static void
{
sec++;
}
}
/*
* Convert a high-resolution time from gethrtime() to a TOD (fmd_timeval_t).
* We convert 'tod_base' to nanoseconds, adjust it based on the difference
* between the corresponding 'hrt_base' and the event high-res time 'hrt',
* and then repack the result into ftv_sec and ftv_nsec for our output.
*/
void
{
}
/*
* Convert a TOD (fmd_timeval_t) to a high-resolution time from gethrtime().
* Note that since TOD occurred in the past, the resulting value may be a
* negative number according the current gethrtime() clock value.
*/
void
{
}
/*
* Adjust a high-resolution time based on the low bits of time stored in ENA.
* The assumption here in that ENA won't wrap between the time it is computed
* and the time the error is queued (when we capture a full 64-bits of hrtime).
* We extract the relevant ENA time bits as 't0' and subtract the difference
* between these bits and the corresponding low bits of 'hrt' from 'hrt'.
*
* Under xVM dom0, the UE ereport is prepared after panic, therefore
* the full 64-bit hrtime of 't0' can be bigger than 'hrt'. In such case,
* we should just return 'hrt'.
*
* 't0' contains only the low bits of 64bit hrtime. It is tricky to tell
* whether 'hrt' or 't0' happened first. We assume there should be short
* period between 'hrt' and 't0', therefore to check which one came first, we
* test their subtraction against the highest bit of mask, if the bit is not
* set, then 't0' is earlier. This is equivalent to
* ((hrt - t0) & mask) < ((mask + 1) / 2)
*/
{
switch (ENA_FORMAT(ena)) {
case FM_ENA_FMT1:
break;
case FM_ENA_FMT2:
break;
}
return (hrt);
}
/*
* To implement a simulated clock, we keep track of an hrtime_t value which
* starts at zero and is incremented only by fmd_time_addhrtime() (i.e. when
* the driver of the simulation requests that the clock advance). We sample
* the native time-of-day clock once at the start of the simulation and then
* return subsequent time-of-day values by adjusting TOD using the hrtime_t
* clock setting. Simulated nanosleep (fmd_time_waithrtime() entry point) is
* implemented by waiting on fts->fts_cv for the hrtime_t to increment.
*/
static void *
fmd_simulator_init(void)
{
fts->fts_cancel = 0;
return (fts);
}
static void
{
}
/*ARGSUSED*/
static int
{
return (0);
}
static hrtime_t
fmd_simulator_hrt(void)
{
return (hrt);
}
static void
{
else
}
static void
{
/*
* If the delta causes time to wrap because we've reached the simulated
* apocalypse, then wait forever. We make 'hrt' unsigned so that the
* while-loop comparison fts_hrt < UINT64_MAX will always return true.
*/
hrt = UINT64_MAX;
else
if (fts->fts_cancel != 0)
}
/*ARGSUSED*/
static void
{
fts->fts_cancel++;
}
/*
* Native time is implemented by calls to gethrtime() and gettimeofday(), which
* are stored directly in the native time ops-vector defined below. To wait on
* the native clock we use nanosleep(), which we can abort using a signal. The
* implementation assumes that callers will have a SIGALRM handler installed.
*/
static void
{
}
static void
{
}
static void *
fmd_time_nop(void)
{
return (NULL);
}
(void *(*)())fmd_time_nop, /* fto_init */
(void (*)())fmd_time_nop, /* fto_fini */
gettimeofday, /* fto_gettimeofday */
gethrtime, /* fto_gethrtime */
(void (*)())fmd_time_nop, /* fto_addhrtime */
fmd_native_wait, /* fto_waithrtime */
fmd_native_cancel, /* fto_waitcancel */
};
fmd_simulator_init, /* fto_init */
fmd_simulator_fini, /* fto_fini */
fmd_simulator_tod, /* fto_gettimeofday */
fmd_simulator_hrt, /* fto_gethrtime */
fmd_simulator_add, /* fto_addhrtime */
fmd_simulator_wait, /* fto_waithrtime */
fmd_simulator_cancel, /* fto_waitcancel */
};