aboutsummaryrefslogtreecommitdiff
path: root/common/uapi
diff options
context:
space:
mode:
Diffstat (limited to 'common/uapi')
-rw-r--r--common/uapi/dispatch.c3
-rw-r--r--common/uapi/timers.c40
2 files changed, 38 insertions, 5 deletions
diff --git a/common/uapi/dispatch.c b/common/uapi/dispatch.c
index b16b255..fe86df0 100644
--- a/common/uapi/dispatch.c
+++ b/common/uapi/dispatch.c
@@ -26,6 +26,7 @@ static const sys_t syscall_table[] = {
/* timers */
[SYS_TIMEBASE] = sys_timebase,
+ [SYS_TICKS] = sys_ticks,
[SYS_REQ_REL_TIMER] = sys_req_rel_timer,
[SYS_REQ_ABS_TIMER] = sys_req_abs_timer,
[SYS_FREE_TIMER] = sys_free_timer,
@@ -93,6 +94,8 @@ struct sys_ret syscall_dispatch(sys_arg_t syscall, sys_arg_t a, sys_arg_t b,
if (check_canary(t)) {
bug("Syscall %zu overwrote stack canary\n", syscall);
+ /** @todo should probably halt, as the system is likely in an
+ * unstable state. */
return (struct sys_ret){ ERR_INT, 0 };
}
diff --git a/common/uapi/timers.c b/common/uapi/timers.c
index b6f9b95..d6c6286 100644
--- a/common/uapi/timers.c
+++ b/common/uapi/timers.c
@@ -9,8 +9,10 @@
#include <apos/timer.h>
#include <apos/uapi.h>
+#include <arch/timer.h>
+
/**
- * Convert arch-specific register values \c ticks and \c repeat to \c ticks_t.
+ * Convert arch-specific register values \p ticks and \p mult to \ref ticks_t.
*
* If we're on a 32bit system, one register can't contain a tick value,
* so we use two registers and combine them into one value and let the compiler
@@ -18,7 +20,7 @@
*
* @param ticks Register width tick value.
* @param mult Register width repeat value.
- * @return Corresponding \c ticks_t value.
+ * @return Corresponding \ref ticks_t value.
*/
static ticks_t scaled_ticks(sys_arg_t ticks, sys_arg_t mult)
{
@@ -33,17 +35,45 @@ static ticks_t scaled_ticks(sys_arg_t ticks, sys_arg_t mult)
/**
* Timebase syscall handler.
*
- * @return \ref OK and resolution of system timer in Hz.
+ * @return \ref OK and resolution of system timer in Hz if on 64bit system,
+ * otherwise high bits of resolutio in first register and low bits in second.
*/
SYSCALL_DEFINE0(timebase)()
{
- return (struct sys_ret){ OK, secs_to_ticks(1) };
+ ticks_t t = secs_to_ticks(1);
+#if defined(_LP64)
+ return (struct sys_ret){ OK, t };
+#else
+ return (struct sys_ret){ t >> 32, t };
+#endif
+}
+
+/**
+ * Current ticks syscall handler.
+ *
+ * Note that most platforms allow user level read access to hardware timers, and
+ * should be preferred over this syscall on such platforms. Still, for
+ * completeness sake.
+ *
+ * @return \ref OK and the current ticks when on 64bit systems, otherwise high
+ * 32 bits of ticks in first register and low 32 bits in second.
+ * \todo 32bit systems are arguably a bit unsafe with this method, should I
+ * instead provide ticks_low and ticks_high or something?
+ */
+SYSCALL_DEFINE0(ticks)()
+{
+ ticks_t t = current_ticks();
+#if defined(_LP64)
+ return (struct sys_ret){ OK, t };
+#else
+ return (struct sys_ret){ t >> 32, t };
+#endif
}
/**
* Relative timer request syscall handler.
*
- * \note On 64bit systems, \c repeat is ignored as \c ticks register is large
+ * \note On 64bit systems, \p mult is ignored as \p ticks register is large
* enough to contain essentially any timepoint we want. A couple thousand years
* when the clock runs at 5GHz, if I'm not completely mistaken.
*