All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/25] Dovetail integration, next round
@ 2021-05-20 21:44 Jan Kiszka
  2021-05-20 21:44 ` [PATCH 01/25] cobalt/kernel: ipipe: rename xnsched_realtime_domain to xnsched_primary_domain Jan Kiszka
                   ` (24 more replies)
  0 siblings, 25 replies; 26+ messages in thread
From: Jan Kiszka @ 2021-05-20 21:44 UTC (permalink / raw)
  To: xenomai

This is just half-way through to one working arch. A split at this at
the point libcobalt is refactored for dovetail ticks. Test target for
this part remains I-pipe, i.e. the check for no regressions on it.

Jan


CC: Hongzhan Chen <hongzhan.chen@intel.com>
CC: Philippe Gerum <rpm@xenomai.org>

Hongzhan Chen (12):
  cobalt/irq: dovetail: implement out-of-band irq management and
    handling
  cobalt/kevents: dovetail: enable back tracing
  cobalt/kernel: dovetail: implement sirq services
  cobalt/sched: dovetail: add task control block initializers
  cobalt/clock: dovetail: provide backend code to CLOCK_HOST_REALTIME
  cobalt/init: dovetail: add oob stage enabling, disabling services
  cobalt/tick: dovetail: install/uninstall proxy tick device
  cobalt/tick: dovetail: implement pipeline_set_timer_shot()
  cobalt/tick: dovetail: implement pipeline_timer_name()
  cobalt/timer: pipeline: abstract handling of ONESHOT_STOPPED mode
  cobalt/timer: dovetail: handle ONESHOT_STOPPED mode
  cobalt/clock: dovetail: implement pipeline_read_cycle_counter()

Jan Kiszka (3):
  cobalt/x86: ipipe: Remove leftover from x86_32 removal
  cobalt/x86: ipipe: Drop unused strncpy_from_user_nocheck
  cobalt/x86: Move shared headers out of pipeline specific folder

Philippe Gerum (10):
  cobalt/kernel: ipipe: rename xnsched_realtime_domain to
    xnsched_primary_domain
  cobalt/kevents: dovetail: drop call to obsolete force_commit_memory()
  cobalt/intr: dovetail: implement interrupt management, handling
  cobalt/x86: dovetail: add architecture bits
  cobalt/timer: Check if nklock is held in timer services
  cobalt/tick: dovetail: flatten the call stack to pipeline services
  lib/cobalt: ticks: drop cobalt_read_hrclock()
  lib/cobalt: dovetail: allow representing time as count of nanoseconds
  lib/cobalt: add default wrapper to clock_settime()
  lib/cobalt: dovetail: use clock_gettime() vcall for reading timestamps

 .../cobalt/kernel/dovetail/pipeline/clock.h   |  30 +-
 include/cobalt/kernel/dovetail/pipeline/irq.h |  24 ++
 .../kernel/dovetail/pipeline/pipeline.h       |  40 +--
 .../cobalt/kernel/dovetail/pipeline/sirq.h    |  28 +-
 .../cobalt/kernel/dovetail/pipeline/tick.h    |   4 +
 .../cobalt/kernel/ipipe/pipeline/pipeline.h   |   2 +-
 include/cobalt/kernel/ipipe/pipeline/tick.h   |   6 +
 include/cobalt/kernel/sched.h                 |   5 +
 include/cobalt/ticks.h                        |  50 +++-
 kernel/cobalt/arch/x86/dovetail/Makefile      |   5 +
 kernel/cobalt/arch/x86/dovetail/c1e.c         |   1 +
 .../include/asm/xenomai/calibration.h}        |  34 +--
 .../x86/dovetail/include/asm/xenomai/fptest.h |  70 +++++
 .../include/asm/xenomai/machine.h             |   7 +-
 .../include/asm/xenomai/syscall.h             |  19 +-
 .../x86/dovetail/include/asm/xenomai/thread.h |  38 +++
 .../arch/x86/{ipipe => dovetail}/machine.c    |  29 +-
 kernel/cobalt/arch/x86/dovetail/smi.c         |   1 +
 .../x86/{ipipe => }/include/asm/xenomai/c1e.h |   0
 .../include/asm/xenomai/features.h            |   0
 .../x86/{ipipe => }/include/asm/xenomai/smi.h |   0
 .../include/asm/xenomai/syscall32-table.h     |   0
 .../include/asm/xenomai/syscall32.h           |   0
 .../include/asm/xenomai/wrappers.h            |   0
 .../x86/ipipe/include/asm/xenomai/machine.h   |   4 -
 .../x86/ipipe/include/asm/xenomai/syscall.h   |   8 -
 kernel/cobalt/arch/x86/ipipe/machine.c        |  19 --
 kernel/cobalt/arch/x86/ipipe/smi.c            |   4 +-
 kernel/cobalt/clock.c                         |   2 +-
 kernel/cobalt/dovetail/Makefile               |   2 +-
 kernel/cobalt/dovetail/init.c                 |   4 +-
 kernel/cobalt/dovetail/intr.c                 | 130 ++++++++
 kernel/cobalt/dovetail/kevents.c              |  15 +-
 kernel/cobalt/dovetail/sched.c                |  12 +-
 kernel/cobalt/dovetail/tick.c                 | 141 ++++++++-
 kernel/cobalt/ipipe/init.c                    |  12 +-
 kernel/cobalt/ipipe/intr.c                    |  20 +-
 kernel/cobalt/ipipe/kevents.c                 |   2 +-
 kernel/cobalt/ipipe/syscall.c                 |   2 +-
 kernel/cobalt/timer.c                         |  17 +-
 lib/cobalt/Makefile.am                        |   1 +
 .../arch/arm/include/asm/xenomai/time.h       |  16 +
 .../arch/arm64/include/asm/xenomai/time.h     |  16 +
 .../arch/powerpc/include/asm/xenomai/time.h   |  16 +
 .../arch/x86/include/asm/xenomai/time.h       |  16 +
 lib/cobalt/clock.c                            | 107 ++++---
 lib/cobalt/internal.h                         |   6 +
 lib/cobalt/parse_vdso.c                       | 281 ++++++++++++++++++
 lib/cobalt/ticks.c                            |  65 ++--
 lib/cobalt/wrappers.c                         |   6 +
 50 files changed, 1060 insertions(+), 257 deletions(-)
 create mode 100644 include/cobalt/kernel/dovetail/pipeline/irq.h
 create mode 100644 kernel/cobalt/arch/x86/dovetail/Makefile
 create mode 120000 kernel/cobalt/arch/x86/dovetail/c1e.c
 copy kernel/cobalt/arch/x86/{ipipe/include/asm/xenomai/machine.h => dovetail/include/asm/xenomai/calibration.h} (52%)
 create mode 100644 kernel/cobalt/arch/x86/dovetail/include/asm/xenomai/fptest.h
 copy kernel/cobalt/arch/x86/{ipipe => dovetail}/include/asm/xenomai/machine.h (88%)
 copy kernel/cobalt/arch/x86/{ipipe => dovetail}/include/asm/xenomai/syscall.h (87%)
 create mode 100644 kernel/cobalt/arch/x86/dovetail/include/asm/xenomai/thread.h
 copy kernel/cobalt/arch/x86/{ipipe => dovetail}/machine.c (80%)
 create mode 120000 kernel/cobalt/arch/x86/dovetail/smi.c
 rename kernel/cobalt/arch/x86/{ipipe => }/include/asm/xenomai/c1e.h (100%)
 rename kernel/cobalt/arch/x86/{ipipe => }/include/asm/xenomai/features.h (100%)
 rename kernel/cobalt/arch/x86/{ipipe => }/include/asm/xenomai/smi.h (100%)
 rename kernel/cobalt/arch/x86/{ipipe => }/include/asm/xenomai/syscall32-table.h (100%)
 rename kernel/cobalt/arch/x86/{ipipe => }/include/asm/xenomai/syscall32.h (100%)
 rename kernel/cobalt/arch/x86/{ipipe => }/include/asm/xenomai/wrappers.h (100%)
 create mode 100644 kernel/cobalt/dovetail/intr.c
 create mode 100644 lib/cobalt/arch/arm/include/asm/xenomai/time.h
 create mode 100644 lib/cobalt/arch/arm64/include/asm/xenomai/time.h
 create mode 100644 lib/cobalt/arch/powerpc/include/asm/xenomai/time.h
 create mode 100644 lib/cobalt/arch/x86/include/asm/xenomai/time.h
 create mode 100644 lib/cobalt/parse_vdso.c

-- 
2.26.2



^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 01/25] cobalt/kernel: ipipe: rename xnsched_realtime_domain to xnsched_primary_domain
  2021-05-20 21:44 [PATCH 00/25] Dovetail integration, next round Jan Kiszka
@ 2021-05-20 21:44 ` Jan Kiszka
  2021-05-20 21:44 ` [PATCH 02/25] cobalt/kevents: dovetail: drop call to obsolete force_commit_memory() Jan Kiszka
                   ` (23 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Jan Kiszka @ 2021-05-20 21:44 UTC (permalink / raw)
  To: xenomai

From: Philippe Gerum <rpm@xenomai.org>

This symbol is now I-pipe specific, stick to the I-pipe nomenclature
when referring to the high priority execution domain.

Signed-off-by: Philippe Gerum <rpm@xenomai.org>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 .../cobalt/kernel/ipipe/pipeline/pipeline.h   |  2 +-
 kernel/cobalt/ipipe/init.c                    | 12 +++++------
 kernel/cobalt/ipipe/intr.c                    | 20 +++++++++----------
 kernel/cobalt/ipipe/kevents.c                 |  2 +-
 kernel/cobalt/ipipe/syscall.c                 |  2 +-
 5 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/include/cobalt/kernel/ipipe/pipeline/pipeline.h b/include/cobalt/kernel/ipipe/pipeline/pipeline.h
index e9e357bb06..fda962568a 100644
--- a/include/cobalt/kernel/ipipe/pipeline/pipeline.h
+++ b/include/cobalt/kernel/ipipe/pipeline/pipeline.h
@@ -12,7 +12,7 @@
 #include <pipeline/machine.h>
 #include <asm/xenomai/features.h>
 
-#define xnsched_realtime_domain  cobalt_pipeline.domain
+#define xnsched_primary_domain  cobalt_pipeline.domain
 
 #define PIPELINE_NR_IRQS  IPIPE_NR_IRQS
 
diff --git a/kernel/cobalt/ipipe/init.c b/kernel/cobalt/ipipe/init.c
index 1b3696b2f2..c199f00def 100644
--- a/kernel/cobalt/ipipe/init.c
+++ b/kernel/cobalt/ipipe/init.c
@@ -30,7 +30,7 @@ int __init pipeline_init(void)
 			return ret;
 	}
 
-	ipipe_register_head(&xnsched_realtime_domain, "Xenomai");
+	ipipe_register_head(&xnsched_primary_domain, "Xenomai");
 
 	virq = ipipe_alloc_virq();
 	if (virq == 0)
@@ -38,7 +38,7 @@ int __init pipeline_init(void)
 
 	cobalt_pipeline.escalate_virq = virq;
 
-	ipipe_request_irq(&xnsched_realtime_domain,
+	ipipe_request_irq(&xnsched_primary_domain,
 			  cobalt_pipeline.escalate_virq,
 			  (ipipe_irq_handler_t)__xnsched_run_handler,
 			  NULL, NULL);
@@ -50,11 +50,11 @@ int __init pipeline_init(void)
 	return 0;
 
 fail_clock:
-	ipipe_free_irq(&xnsched_realtime_domain,
+	ipipe_free_irq(&xnsched_primary_domain,
 		       cobalt_pipeline.escalate_virq);
 	ipipe_free_virq(cobalt_pipeline.escalate_virq);
 fail_escalate:
-	ipipe_unregister_head(&xnsched_realtime_domain);
+	ipipe_unregister_head(&xnsched_primary_domain);
 
 	if (cobalt_machine.cleanup)
 		cobalt_machine.cleanup();
@@ -72,8 +72,8 @@ int __init pipeline_late_init(void)
 
 __init void pipeline_cleanup(void)
 {
-	ipipe_unregister_head(&xnsched_realtime_domain);
-	ipipe_free_irq(&xnsched_realtime_domain,
+	ipipe_unregister_head(&xnsched_primary_domain);
+	ipipe_free_irq(&xnsched_primary_domain,
 		       cobalt_pipeline.escalate_virq);
 	ipipe_free_virq(cobalt_pipeline.escalate_virq);
 	ipipe_timers_release();
diff --git a/kernel/cobalt/ipipe/intr.c b/kernel/cobalt/ipipe/intr.c
index 91b63d4900..0c1cc4be45 100644
--- a/kernel/cobalt/ipipe/intr.c
+++ b/kernel/cobalt/ipipe/intr.c
@@ -464,7 +464,7 @@ static inline bool cobalt_owns_irq(int irq)
 {
 	ipipe_irq_handler_t h;
 
-	h = __ipipe_irq_handler(&xnsched_realtime_domain, irq);
+	h = __ipipe_irq_handler(&xnsched_primary_domain, irq);
 
 	return h == xnintr_vec_handler ||
 		h == xnintr_edge_vec_handler ||
@@ -507,7 +507,7 @@ static inline int xnintr_irq_attach(struct xnintr *intr)
 		}
 		vec->unhandled = 0;
 
-		ret = ipipe_request_irq(&xnsched_realtime_domain,
+		ret = ipipe_request_irq(&xnsched_primary_domain,
 					intr->irq, handler, intr,
 					(ipipe_irq_ackfn_t)intr->iack);
 		if (ret)
@@ -540,7 +540,7 @@ static inline void xnintr_irq_detach(struct xnintr *intr)
 
 			/* Release the IRQ line if this was the last user */
 			if (vec->handlers == NULL)
-				ipipe_free_irq(&xnsched_realtime_domain, intr->irq);
+				ipipe_free_irq(&xnsched_primary_domain, intr->irq);
 
 			return;
 		}
@@ -564,7 +564,7 @@ static inline bool cobalt_owns_irq(int irq)
 {
 	ipipe_irq_handler_t h;
 
-	h = __ipipe_irq_handler(&xnsched_realtime_domain, irq);
+	h = __ipipe_irq_handler(&xnsched_primary_domain, irq);
 
 	return h == xnintr_irq_handler;
 }
@@ -572,7 +572,7 @@ static inline bool cobalt_owns_irq(int irq)
 static inline struct xnintr *xnintr_vec_first(unsigned int irq)
 {
 	return cobalt_owns_irq(irq) ?
-		__ipipe_irq_cookie(&xnsched_realtime_domain, irq) : NULL;
+		__ipipe_irq_cookie(&xnsched_primary_domain, irq) : NULL;
 }
 
 static inline struct xnintr *xnintr_vec_next(struct xnintr *prev)
@@ -582,7 +582,7 @@ static inline struct xnintr *xnintr_vec_next(struct xnintr *prev)
 
 static inline int xnintr_irq_attach(struct xnintr *intr)
 {
-	return ipipe_request_irq(&xnsched_realtime_domain,
+	return ipipe_request_irq(&xnsched_primary_domain,
 				 intr->irq, xnintr_irq_handler, intr,
 				 (ipipe_irq_ackfn_t)intr->iack);
 }
@@ -592,7 +592,7 @@ static inline void xnintr_irq_detach(struct xnintr *intr)
 	int irq = intr->irq;
 
 	xnlock_get(&vectors[irq].lock);
-	ipipe_free_irq(&xnsched_realtime_domain, irq);
+	ipipe_free_irq(&xnsched_primary_domain, irq);
 	xnlock_put(&vectors[irq].lock);
 
 	sync_stat_references(intr);
@@ -630,7 +630,7 @@ static void xnintr_irq_handler(unsigned int irq, void *cookie)
 	 * interrupt service routine, so the scheduler pointer will
 	 * remain valid throughout this function.
 	 */
-	intr = __ipipe_irq_cookie(&xnsched_realtime_domain, irq);
+	intr = __ipipe_irq_cookie(&xnsched_primary_domain, irq);
 	if (unlikely(intr == NULL))
 		goto done;
 #else
@@ -1162,14 +1162,14 @@ static int irq_vfile_show(struct xnvfile_regular_iterator *it,
 		xnvfile_printf(it, "        CPU%d", cpu);
 
 	for (irq = 0; irq < IPIPE_NR_IRQS; irq++) {
-		if (__ipipe_irq_handler(&xnsched_realtime_domain, irq) == NULL)
+		if (__ipipe_irq_handler(&xnsched_primary_domain, irq) == NULL)
 			continue;
 
 		xnvfile_printf(it, "\n%5d:", irq);
 
 		for_each_realtime_cpu(cpu) {
 			xnvfile_printf(it, "%12lu",
-				       __ipipe_cpudata_irq_hits(&xnsched_realtime_domain, cpu,
+				       __ipipe_cpudata_irq_hits(&xnsched_primary_domain, cpu,
 								irq));
 		}
 
diff --git a/kernel/cobalt/ipipe/kevents.c b/kernel/cobalt/ipipe/kevents.c
index f0314cd440..617e5cb6af 100644
--- a/kernel/cobalt/ipipe/kevents.c
+++ b/kernel/cobalt/ipipe/kevents.c
@@ -853,7 +853,7 @@ int pipeline_trap_kevents(void)
 {
 	init_hostrt();
 	ipipe_set_hooks(ipipe_root_domain, IPIPE_SYSCALL|IPIPE_KEVENT);
-	ipipe_set_hooks(&xnsched_realtime_domain, IPIPE_SYSCALL|IPIPE_TRAP);
+	ipipe_set_hooks(&xnsched_primary_domain, IPIPE_SYSCALL|IPIPE_TRAP);
 
 	return 0;
 }
diff --git a/kernel/cobalt/ipipe/syscall.c b/kernel/cobalt/ipipe/syscall.c
index 18aa996bd0..867a81ec24 100644
--- a/kernel/cobalt/ipipe/syscall.c
+++ b/kernel/cobalt/ipipe/syscall.c
@@ -15,7 +15,7 @@ int ipipe_syscall_hook(struct ipipe_domain *ipd, struct pt_regs *regs)
 	if (unlikely(is_secondary_domain()))
 		return handle_root_syscall(regs);
 
-	return handle_head_syscall(ipd != &xnsched_realtime_domain, regs);
+	return handle_head_syscall(ipd != &xnsched_primary_domain, regs);
 }
 
 int ipipe_fastcall_hook(struct pt_regs *regs)
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 02/25] cobalt/kevents: dovetail: drop call to obsolete force_commit_memory()
  2021-05-20 21:44 [PATCH 00/25] Dovetail integration, next round Jan Kiszka
  2021-05-20 21:44 ` [PATCH 01/25] cobalt/kernel: ipipe: rename xnsched_realtime_domain to xnsched_primary_domain Jan Kiszka
@ 2021-05-20 21:44 ` Jan Kiszka
  2021-05-20 21:44 ` [PATCH 03/25] cobalt/intr: dovetail: implement interrupt management, handling Jan Kiszka
                   ` (22 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Jan Kiszka @ 2021-05-20 21:44 UTC (permalink / raw)
  To: xenomai

From: Philippe Gerum <rpm@xenomai.org>

A process is now marked for COW-breaking on fork() upon the first call
to dovetail_init_altsched(), and must ensure its memory is locked via
a call to mlockall(MCL_CURRENT|MCL_FUTURE) as usual.

As a result, force_commit_memory() became pointless and was removed
from the Dovetail interface.

Signed-off-by: Philippe Gerum <rpm@xenomai.org>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 kernel/cobalt/dovetail/kevents.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/kernel/cobalt/dovetail/kevents.c b/kernel/cobalt/dovetail/kevents.c
index 5efe30c22d..64f6f421c1 100644
--- a/kernel/cobalt/dovetail/kevents.c
+++ b/kernel/cobalt/dovetail/kevents.c
@@ -516,7 +516,8 @@ void handle_inband_event(enum inband_event_type event, void *data)
 }
 
 #ifdef CONFIG_MMU
-static inline int disable_ondemand_memory(void)
+
+int pipeline_prepare_current(void)
 {
 	struct task_struct *p = current;
 	kernel_siginfo_t si;
@@ -527,15 +528,9 @@ static inline int disable_ondemand_memory(void)
 		si.si_code = SI_QUEUE;
 		si.si_int = SIGDEBUG_NOMLOCK | sigdebug_marker;
 		send_sig_info(SIGDEBUG, &si, p);
-		return 0;
 	}
 
-	return force_commit_memory();
-}
-
-int pipeline_prepare_current(void)
-{
-	return disable_ondemand_memory();
+	return 0;
 }
 
 static inline int get_mayday_prot(void)
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 03/25] cobalt/intr: dovetail: implement interrupt management, handling
  2021-05-20 21:44 [PATCH 00/25] Dovetail integration, next round Jan Kiszka
  2021-05-20 21:44 ` [PATCH 01/25] cobalt/kernel: ipipe: rename xnsched_realtime_domain to xnsched_primary_domain Jan Kiszka
  2021-05-20 21:44 ` [PATCH 02/25] cobalt/kevents: dovetail: drop call to obsolete force_commit_memory() Jan Kiszka
@ 2021-05-20 21:44 ` Jan Kiszka
  2021-05-20 21:44 ` [PATCH 04/25] cobalt/irq: dovetail: implement out-of-band irq management and handling Jan Kiszka
                   ` (21 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Jan Kiszka @ 2021-05-20 21:44 UTC (permalink / raw)
  To: xenomai

From: Philippe Gerum <rpm@xenomai.org>

We are using regular request/free_irq under dovetail. This also means
there is no extra task to be done in the interrupt enable/disable
services.

The affinity hint set during request needs to be cleared before freeing
the IRQ, or Linux will complain.

Signed-off-by: Philippe Gerum <rpm@xenomai.org>
[Jan: clear affinity hint on free, drop explicit enable/disable_irq]
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 include/cobalt/kernel/dovetail/pipeline/irq.h |  24 ++++
 kernel/cobalt/dovetail/Makefile               |   2 +-
 kernel/cobalt/dovetail/intr.c                 | 130 ++++++++++++++++++
 3 files changed, 155 insertions(+), 1 deletion(-)
 create mode 100644 include/cobalt/kernel/dovetail/pipeline/irq.h
 create mode 100644 kernel/cobalt/dovetail/intr.c

diff --git a/include/cobalt/kernel/dovetail/pipeline/irq.h b/include/cobalt/kernel/dovetail/pipeline/irq.h
new file mode 100644
index 0000000000..55d9b8ff17
--- /dev/null
+++ b/include/cobalt/kernel/dovetail/pipeline/irq.h
@@ -0,0 +1,24 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _COBALT_KERNEL_DOVETAIL_IRQ_H
+#define _COBALT_KERNEL_DOVETAIL_IRQ_H
+
+static inline void xnintr_init_proc(void)
+{
+	/* N/A */
+}
+
+static inline void xnintr_cleanup_proc(void)
+{
+	/* N/A */
+}
+
+static inline int xnintr_mount(void)
+{
+	/* N/A */
+	return 0;
+}
+
+#endif /* !_COBALT_KERNEL_DOVETAIL_IRQ_H */
diff --git a/kernel/cobalt/dovetail/Makefile b/kernel/cobalt/dovetail/Makefile
index 1ecbd97a96..f49d3a06b2 100644
--- a/kernel/cobalt/dovetail/Makefile
+++ b/kernel/cobalt/dovetail/Makefile
@@ -2,4 +2,4 @@ ccflags-y += -I$(srctree)/kernel
 
 obj-y +=	pipeline.o
 
-pipeline-y :=	init.o kevents.o sched.o tick.o syscall.o
+pipeline-y :=	init.o kevents.o sched.o tick.o syscall.o intr.o
diff --git a/kernel/cobalt/dovetail/intr.c b/kernel/cobalt/dovetail/intr.c
new file mode 100644
index 0000000000..60d5bf882c
--- /dev/null
+++ b/kernel/cobalt/dovetail/intr.c
@@ -0,0 +1,130 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irq_pipeline.h>
+#include <linux/tick.h>
+#include <cobalt/kernel/sched.h>
+#include <cobalt/kernel/lock.h>
+#include <cobalt/kernel/intr.h>
+
+void xnintr_host_tick(struct xnsched *sched) /* hard irqs off */
+{
+	sched->lflags &= ~XNHTICK;
+	tick_notify_proxy();
+}
+
+/*
+ * Low-level core clock irq handler. This one forwards ticks from the
+ * Xenomai platform timer to nkclock exclusively.
+ */
+void xnintr_core_clock_handler(void)
+{
+	struct xnsched *sched;
+
+	xnlock_get(&nklock);
+	xnclock_tick(&nkclock);
+	xnlock_put(&nklock);
+
+	/*
+	 * If the core clock interrupt preempted a real-time thread,
+	 * any transition to the root thread has already triggered a
+	 * host tick propagation from xnsched_run(), so at this point,
+	 * we only need to propagate the host tick in case the
+	 * interrupt preempted the root thread.
+	 */
+	sched = xnsched_current();
+	if ((sched->lflags & XNHTICK) &&
+	    xnthread_test_state(sched->curr, XNROOT))
+		xnintr_host_tick(sched);
+}
+
+static irqreturn_t xnintr_irq_handler(int irq, void *dev_id)
+{
+	struct xnintr *intr = dev_id;
+	int ret;
+
+	ret = intr->isr(intr);
+	XENO_WARN_ON_ONCE(USER, (ret & XN_IRQ_STATMASK) == 0);
+
+	if (ret & XN_IRQ_DISABLE)
+		disable_irq(irq);
+	else if (ret & XN_IRQ_PROPAGATE)
+		irq_post_inband(irq);
+
+	return ret & XN_IRQ_NONE ? IRQ_NONE : IRQ_HANDLED;
+}
+
+int xnintr_init(struct xnintr *intr, const char *name,
+		unsigned int irq, xnisr_t isr, xniack_t iack,
+		int flags)
+{
+	secondary_mode_only();
+
+	intr->irq = irq;
+	intr->isr = isr;
+	intr->iack = NULL;	/* unused */
+	intr->cookie = NULL;
+	intr->name = name ? : "<unknown>";
+	intr->flags = flags;
+	intr->status = 0;
+	intr->unhandled = 0;	/* unused */
+	raw_spin_lock_init(&intr->lock); /* unused */
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(xnintr_init);
+
+void xnintr_destroy(struct xnintr *intr)
+{
+	secondary_mode_only();
+	xnintr_detach(intr);
+}
+EXPORT_SYMBOL_GPL(xnintr_destroy);
+
+int xnintr_attach(struct xnintr *intr, void *cookie)
+{
+	int ret;
+
+	secondary_mode_only();
+
+	intr->cookie = cookie;
+
+	ret = irq_set_affinity_hint(intr->irq, &xnsched_realtime_cpus);
+	if (ret)
+		return ret;
+
+	return request_irq(intr->irq, xnintr_irq_handler, IRQF_OOB,
+			intr->name, intr);
+}
+EXPORT_SYMBOL_GPL(xnintr_attach);
+
+void xnintr_detach(struct xnintr *intr)
+{
+	secondary_mode_only();
+	irq_set_affinity_hint(intr->irq, NULL);
+	free_irq(intr->irq, intr);
+}
+EXPORT_SYMBOL_GPL(xnintr_detach);
+
+void xnintr_enable(struct xnintr *intr)
+{
+}
+EXPORT_SYMBOL_GPL(xnintr_enable);
+
+void xnintr_disable(struct xnintr *intr)
+{
+}
+EXPORT_SYMBOL_GPL(xnintr_disable);
+
+void xnintr_affinity(struct xnintr *intr, cpumask_t cpumask)
+{
+	int ret;
+
+	secondary_mode_only();
+	ret = irq_set_affinity_hint(intr->irq, &cpumask);
+
+	WARN_ON_ONCE(ret);
+}
+EXPORT_SYMBOL_GPL(xnintr_affinity);
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 04/25] cobalt/irq: dovetail: implement out-of-band irq management and handling
  2021-05-20 21:44 [PATCH 00/25] Dovetail integration, next round Jan Kiszka
                   ` (2 preceding siblings ...)
  2021-05-20 21:44 ` [PATCH 03/25] cobalt/intr: dovetail: implement interrupt management, handling Jan Kiszka
@ 2021-05-20 21:44 ` Jan Kiszka
  2021-05-20 21:44 ` [PATCH 05/25] cobalt/kevents: dovetail: enable back tracing Jan Kiszka
                   ` (20 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Jan Kiszka @ 2021-05-20 21:44 UTC (permalink / raw)
  To: xenomai

From: Hongzhan Chen <hongzhan.chen@intel.com>

implement oob irq request and free and post for both
TIMER_OOB_IPI and RESCHEDULE_OOB_IPI

Signed-off-by: Hongzhan Chen <hongzhan.chen@intel.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 .../kernel/dovetail/pipeline/pipeline.h       | 41 ++++++++++++++-----
 1 file changed, 31 insertions(+), 10 deletions(-)

diff --git a/include/cobalt/kernel/dovetail/pipeline/pipeline.h b/include/cobalt/kernel/dovetail/pipeline/pipeline.h
index 1d4e3f91d6..bbd45d13b3 100644
--- a/include/cobalt/kernel/dovetail/pipeline/pipeline.h
+++ b/include/cobalt/kernel/dovetail/pipeline/pipeline.h
@@ -8,9 +8,12 @@
 #include <linux/irq_pipeline.h>
 #include <cobalt/kernel/assert.h>
 #include <asm/xenomai/features.h>
+#include <pipeline/machine.h>
 
 typedef unsigned long spl_t;
 
+void xnintr_core_clock_handler(void);
+
 /*
  * We only keep the LSB when testing in SMP mode in order to strip off
  * the recursion marker (0x2) the nklock may store there.
@@ -30,18 +33,28 @@ typedef unsigned long spl_t;
 
 #ifdef CONFIG_SMP
 
+static irqreturn_t reschedule_interrupt_handler(int irq, void *dev_id)
+{
+
+	/* Will reschedule from irq_exit_pipeline. */
+
+	return IRQ_HANDLED;
+}
+
 static inline int pipeline_request_resched_ipi(void (*handler)(void))
 {
 	/* Trap the out-of-band rescheduling interrupt. */
-	TODO();
-
-	return 0;
+	return __request_percpu_irq(RESCHEDULE_OOB_IPI,
+			reschedule_interrupt_handler,
+			IRQF_OOB,
+			"Xenomai reschedule",
+			&cobalt_machine_cpudata);
 }
 
 static inline void pipeline_free_resched_ipi(void)
 {
 	/* Release the out-of-band rescheduling interrupt. */
-	TODO();
+	free_percpu_irq(RESCHEDULE_OOB_IPI, &cobalt_machine_cpudata);
 }
 
 static inline void pipeline_send_resched_ipi(const struct cpumask *dest)
@@ -50,21 +63,29 @@ static inline void pipeline_send_resched_ipi(const struct cpumask *dest)
 	 * Trigger the out-of-band rescheduling interrupt on remote
 	 * CPU(s).
 	 */
-	TODO();
+	irq_send_oob_ipi(RESCHEDULE_OOB_IPI, dest);
+}
+
+static irqreturn_t timer_ipi_interrupt_handler(int irq, void *dev_id)
+{
+	xnintr_core_clock_handler();
+
+	return IRQ_HANDLED;
 }
 
 static inline int pipeline_request_timer_ipi(void (*handler)(void))
 {
 	/* Trap the out-of-band timer interrupt. */
-	TODO();
-
-	return 0;
+	return __request_percpu_irq(TIMER_OOB_IPI,
+			timer_ipi_interrupt_handler,
+			IRQF_OOB, "Xenomai timer IPI",
+			&cobalt_machine_cpudata);
 }
 
 static inline void pipeline_free_timer_ipi(void)
 {
 	/* Release the out-of-band timer interrupt. */
-	TODO();
+	free_percpu_irq(TIMER_OOB_IPI, &cobalt_machine_cpudata);
 }
 
 static inline void pipeline_send_timer_ipi(const struct cpumask *dest)
@@ -72,7 +93,7 @@ static inline void pipeline_send_timer_ipi(const struct cpumask *dest)
 	/*
 	 * Trigger the out-of-band timer interrupt on remote CPU(s).
 	 */
-	TODO();
+	irq_send_oob_ipi(TIMER_OOB_IPI, dest);
 }
 
 #else  /* !CONFIG_SMP */
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 05/25] cobalt/kevents: dovetail: enable back tracing
  2021-05-20 21:44 [PATCH 00/25] Dovetail integration, next round Jan Kiszka
                   ` (3 preceding siblings ...)
  2021-05-20 21:44 ` [PATCH 04/25] cobalt/irq: dovetail: implement out-of-band irq management and handling Jan Kiszka
@ 2021-05-20 21:44 ` Jan Kiszka
  2021-05-20 21:44 ` [PATCH 06/25] cobalt/x86: ipipe: Remove leftover from x86_32 removal Jan Kiszka
                   ` (19 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Jan Kiszka @ 2021-05-20 21:44 UTC (permalink / raw)
  To: xenomai

From: Hongzhan Chen <hongzhan.chen@intel.com>

enable back tracing for handle_oob_trap_entry

Signed-off-by: Hongzhan Chen <hongzhan.chen@intel.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 kernel/cobalt/dovetail/kevents.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/kernel/cobalt/dovetail/kevents.c b/kernel/cobalt/dovetail/kevents.c
index 64f6f421c1..a402d55690 100644
--- a/kernel/cobalt/dovetail/kevents.c
+++ b/kernel/cobalt/dovetail/kevents.c
@@ -97,10 +97,8 @@ void handle_oob_trap_entry(unsigned int trapnr, struct pt_regs *regs)
 
 	/*
 	 * Enable back tracing.
-	 *
-	 * trace_cobalt_thread_fault(xnarch_fault_pc(regs), trapnr);
 	 */
-	TODO();
+	trace_cobalt_thread_fault(xnarch_fault_pc(regs), trapnr);
 
 	if (xnthread_test_state(thread, XNROOT))
 		return;
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 06/25] cobalt/x86: ipipe: Remove leftover from x86_32 removal
  2021-05-20 21:44 [PATCH 00/25] Dovetail integration, next round Jan Kiszka
                   ` (4 preceding siblings ...)
  2021-05-20 21:44 ` [PATCH 05/25] cobalt/kevents: dovetail: enable back tracing Jan Kiszka
@ 2021-05-20 21:44 ` Jan Kiszka
  2021-05-20 21:44 ` [PATCH 07/25] cobalt/x86: ipipe: Drop unused strncpy_from_user_nocheck Jan Kiszka
                   ` (18 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Jan Kiszka @ 2021-05-20 21:44 UTC (permalink / raw)
  To: xenomai

From: Jan Kiszka <jan.kiszka@siemens.com>

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 .../cobalt/arch/x86/ipipe/include/asm/xenomai/syscall.h   | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/kernel/cobalt/arch/x86/ipipe/include/asm/xenomai/syscall.h b/kernel/cobalt/arch/x86/ipipe/include/asm/xenomai/syscall.h
index f3f1b476f7..f889f5fc73 100644
--- a/kernel/cobalt/arch/x86/ipipe/include/asm/xenomai/syscall.h
+++ b/kernel/cobalt/arch/x86/ipipe/include/asm/xenomai/syscall.h
@@ -29,19 +29,11 @@
  */
 #define __xn_reg_sys(regs)    ((regs)->orig_ax)
 #define __xn_reg_rval(regs)   ((regs)->ax)
-#ifdef __i386__
-#define __xn_reg_arg1(regs)   ((regs)->bx)
-#define __xn_reg_arg2(regs)   ((regs)->cx)
-#define __xn_reg_arg3(regs)   ((regs)->dx)
-#define __xn_reg_arg4(regs)   ((regs)->si)
-#define __xn_reg_arg5(regs)   ((regs)->di)
-#else /* x86_64 */
 #define __xn_reg_arg1(regs)   ((regs)->di)
 #define __xn_reg_arg2(regs)   ((regs)->si)
 #define __xn_reg_arg3(regs)   ((regs)->dx)
 #define __xn_reg_arg4(regs)   ((regs)->r10)
 #define __xn_reg_arg5(regs)   ((regs)->r8)
-#endif /* x86_64 */
 #define __xn_reg_pc(regs)     ((regs)->ip)
 #define __xn_reg_sp(regs)     ((regs)->sp)
 
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 07/25] cobalt/x86: ipipe: Drop unused strncpy_from_user_nocheck
  2021-05-20 21:44 [PATCH 00/25] Dovetail integration, next round Jan Kiszka
                   ` (5 preceding siblings ...)
  2021-05-20 21:44 ` [PATCH 06/25] cobalt/x86: ipipe: Remove leftover from x86_32 removal Jan Kiszka
@ 2021-05-20 21:44 ` Jan Kiszka
  2021-05-20 21:44 ` [PATCH 08/25] cobalt/x86: Move shared headers out of pipeline specific folder Jan Kiszka
                   ` (17 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Jan Kiszka @ 2021-05-20 21:44 UTC (permalink / raw)
  To: xenomai

From: Jan Kiszka <jan.kiszka@siemens.com>

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 .../x86/ipipe/include/asm/xenomai/machine.h   |  4 ----
 kernel/cobalt/arch/x86/ipipe/machine.c        | 19 -------------------
 2 files changed, 23 deletions(-)

diff --git a/kernel/cobalt/arch/x86/ipipe/include/asm/xenomai/machine.h b/kernel/cobalt/arch/x86/ipipe/include/asm/xenomai/machine.h
index aad700fb67..750eb1ec50 100644
--- a/kernel/cobalt/arch/x86/ipipe/include/asm/xenomai/machine.h
+++ b/kernel/cobalt/arch/x86/ipipe/include/asm/xenomai/machine.h
@@ -29,10 +29,6 @@ static inline __attribute_const__ unsigned long ffnz(unsigned long ul)
 
 #define XNARCH_HOST_TICK_IRQ	__ipipe_hrtimer_irq
 
-long strncpy_from_user_nocheck(char *dst,
-			       const char __user *src,
-			       long count);
-
 /* Read this last to enable default settings. */
 #include <asm-generic/xenomai/machine.h>
 
diff --git a/kernel/cobalt/arch/x86/ipipe/machine.c b/kernel/cobalt/arch/x86/ipipe/machine.c
index 95d2ab2fff..d51a91f975 100644
--- a/kernel/cobalt/arch/x86/ipipe/machine.c
+++ b/kernel/cobalt/arch/x86/ipipe/machine.c
@@ -23,25 +23,6 @@
 #include <asm/xenomai/smi.h>
 #include <asm/xenomai/c1e.h>
 
-long strncpy_from_user_nocheck(char *dst, const char __user *src, long count)
-{
-	int ret;
-	char c;
-	long n;
-	
-	for (n = 0; n < count; n++, src++, dst++) {
-		ret = __xn_get_user(c, src);
-		if (ret)
-			return -EFAULT;
-		*dst = c;
-		if (c == 0)
-			break;
-	}
-
-	return n;
-}
-EXPORT_SYMBOL_GPL(strncpy_from_user_nocheck);
-
 static int mach_x86_init(void)
 {
 	int ret;
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 08/25] cobalt/x86: Move shared headers out of pipeline specific folder
  2021-05-20 21:44 [PATCH 00/25] Dovetail integration, next round Jan Kiszka
                   ` (6 preceding siblings ...)
  2021-05-20 21:44 ` [PATCH 07/25] cobalt/x86: ipipe: Drop unused strncpy_from_user_nocheck Jan Kiszka
@ 2021-05-20 21:44 ` Jan Kiszka
  2021-05-20 21:44 ` [PATCH 09/25] cobalt/x86: dovetail: add architecture bits Jan Kiszka
                   ` (16 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Jan Kiszka @ 2021-05-20 21:44 UTC (permalink / raw)
  To: xenomai

From: Jan Kiszka <jan.kiszka@siemens.com>

Those are not affected by pipeline differences.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 kernel/cobalt/arch/x86/{ipipe => }/include/asm/xenomai/c1e.h      | 0
 kernel/cobalt/arch/x86/{ipipe => }/include/asm/xenomai/features.h | 0
 kernel/cobalt/arch/x86/{ipipe => }/include/asm/xenomai/smi.h      | 0
 .../arch/x86/{ipipe => }/include/asm/xenomai/syscall32-table.h    | 0
 .../cobalt/arch/x86/{ipipe => }/include/asm/xenomai/syscall32.h   | 0
 kernel/cobalt/arch/x86/{ipipe => }/include/asm/xenomai/wrappers.h | 0
 6 files changed, 0 insertions(+), 0 deletions(-)
 rename kernel/cobalt/arch/x86/{ipipe => }/include/asm/xenomai/c1e.h (100%)
 rename kernel/cobalt/arch/x86/{ipipe => }/include/asm/xenomai/features.h (100%)
 rename kernel/cobalt/arch/x86/{ipipe => }/include/asm/xenomai/smi.h (100%)
 rename kernel/cobalt/arch/x86/{ipipe => }/include/asm/xenomai/syscall32-table.h (100%)
 rename kernel/cobalt/arch/x86/{ipipe => }/include/asm/xenomai/syscall32.h (100%)
 rename kernel/cobalt/arch/x86/{ipipe => }/include/asm/xenomai/wrappers.h (100%)

diff --git a/kernel/cobalt/arch/x86/ipipe/include/asm/xenomai/c1e.h b/kernel/cobalt/arch/x86/include/asm/xenomai/c1e.h
similarity index 100%
rename from kernel/cobalt/arch/x86/ipipe/include/asm/xenomai/c1e.h
rename to kernel/cobalt/arch/x86/include/asm/xenomai/c1e.h
diff --git a/kernel/cobalt/arch/x86/ipipe/include/asm/xenomai/features.h b/kernel/cobalt/arch/x86/include/asm/xenomai/features.h
similarity index 100%
rename from kernel/cobalt/arch/x86/ipipe/include/asm/xenomai/features.h
rename to kernel/cobalt/arch/x86/include/asm/xenomai/features.h
diff --git a/kernel/cobalt/arch/x86/ipipe/include/asm/xenomai/smi.h b/kernel/cobalt/arch/x86/include/asm/xenomai/smi.h
similarity index 100%
rename from kernel/cobalt/arch/x86/ipipe/include/asm/xenomai/smi.h
rename to kernel/cobalt/arch/x86/include/asm/xenomai/smi.h
diff --git a/kernel/cobalt/arch/x86/ipipe/include/asm/xenomai/syscall32-table.h b/kernel/cobalt/arch/x86/include/asm/xenomai/syscall32-table.h
similarity index 100%
rename from kernel/cobalt/arch/x86/ipipe/include/asm/xenomai/syscall32-table.h
rename to kernel/cobalt/arch/x86/include/asm/xenomai/syscall32-table.h
diff --git a/kernel/cobalt/arch/x86/ipipe/include/asm/xenomai/syscall32.h b/kernel/cobalt/arch/x86/include/asm/xenomai/syscall32.h
similarity index 100%
rename from kernel/cobalt/arch/x86/ipipe/include/asm/xenomai/syscall32.h
rename to kernel/cobalt/arch/x86/include/asm/xenomai/syscall32.h
diff --git a/kernel/cobalt/arch/x86/ipipe/include/asm/xenomai/wrappers.h b/kernel/cobalt/arch/x86/include/asm/xenomai/wrappers.h
similarity index 100%
rename from kernel/cobalt/arch/x86/ipipe/include/asm/xenomai/wrappers.h
rename to kernel/cobalt/arch/x86/include/asm/xenomai/wrappers.h
-- 
2.26.2



^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 09/25] cobalt/x86: dovetail: add architecture bits
  2021-05-20 21:44 [PATCH 00/25] Dovetail integration, next round Jan Kiszka
                   ` (7 preceding siblings ...)
  2021-05-20 21:44 ` [PATCH 08/25] cobalt/x86: Move shared headers out of pipeline specific folder Jan Kiszka
@ 2021-05-20 21:44 ` Jan Kiszka
  2021-05-20 21:44 ` [PATCH 10/25] cobalt/kernel: dovetail: implement sirq services Jan Kiszka
                   ` (15 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Jan Kiszka @ 2021-05-20 21:44 UTC (permalink / raw)
  To: xenomai

From: Philippe Gerum <rpm@xenomai.org>

Signed-off-by: Philippe Gerum <rpm@xenomai.org>
[Jan: style fixes, dropped/linked shared files]
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 kernel/cobalt/arch/x86/dovetail/Makefile      |  5 ++
 kernel/cobalt/arch/x86/dovetail/c1e.c         |  1 +
 .../include/asm/xenomai/calibration.h         | 37 ++++++++
 .../x86/dovetail/include/asm/xenomai/fptest.h | 70 +++++++++++++++
 .../dovetail/include/asm/xenomai/machine.h    | 34 +++++++
 .../dovetail/include/asm/xenomai/syscall.h    | 90 +++++++++++++++++++
 .../x86/dovetail/include/asm/xenomai/thread.h | 38 ++++++++
 kernel/cobalt/arch/x86/dovetail/machine.c     | 70 +++++++++++++++
 kernel/cobalt/arch/x86/dovetail/smi.c         |  1 +
 kernel/cobalt/arch/x86/ipipe/smi.c            |  4 +-
 10 files changed, 348 insertions(+), 2 deletions(-)
 create mode 100644 kernel/cobalt/arch/x86/dovetail/Makefile
 create mode 120000 kernel/cobalt/arch/x86/dovetail/c1e.c
 create mode 100644 kernel/cobalt/arch/x86/dovetail/include/asm/xenomai/calibration.h
 create mode 100644 kernel/cobalt/arch/x86/dovetail/include/asm/xenomai/fptest.h
 create mode 100644 kernel/cobalt/arch/x86/dovetail/include/asm/xenomai/machine.h
 create mode 100644 kernel/cobalt/arch/x86/dovetail/include/asm/xenomai/syscall.h
 create mode 100644 kernel/cobalt/arch/x86/dovetail/include/asm/xenomai/thread.h
 create mode 100644 kernel/cobalt/arch/x86/dovetail/machine.c
 create mode 120000 kernel/cobalt/arch/x86/dovetail/smi.c

diff --git a/kernel/cobalt/arch/x86/dovetail/Makefile b/kernel/cobalt/arch/x86/dovetail/Makefile
new file mode 100644
index 0000000000..93929b6455
--- /dev/null
+++ b/kernel/cobalt/arch/x86/dovetail/Makefile
@@ -0,0 +1,5 @@
+
+obj-$(CONFIG_XENOMAI) += xenomai.o
+xenomai-y := machine.o smi.o c1e.o
+
+ccflags-y := -I$(srctree)/arch/x86/xenomai/include -I$(srctree)/include/xenomai
diff --git a/kernel/cobalt/arch/x86/dovetail/c1e.c b/kernel/cobalt/arch/x86/dovetail/c1e.c
new file mode 120000
index 0000000000..5dc924ec6c
--- /dev/null
+++ b/kernel/cobalt/arch/x86/dovetail/c1e.c
@@ -0,0 +1 @@
+../ipipe/c1e.c
\ No newline at end of file
diff --git a/kernel/cobalt/arch/x86/dovetail/include/asm/xenomai/calibration.h b/kernel/cobalt/arch/x86/dovetail/include/asm/xenomai/calibration.h
new file mode 100644
index 0000000000..29d2924477
--- /dev/null
+++ b/kernel/cobalt/arch/x86/dovetail/include/asm/xenomai/calibration.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2001,2002,2003,2004,2005 Philippe Gerum <rpm@xenomai.org>.
+ *
+ * Xenomai is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Xenomai is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Xenomai; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+#ifndef _COBALT_X86_ASM_CALIBRATION_H
+#define _COBALT_X86_ASM_CALIBRATION_H
+
+static inline void xnarch_get_latencies(struct xnclock_gravity *p)
+{
+	unsigned long sched_latency;
+
+#if CONFIG_XENO_OPT_TIMING_SCHEDLAT != 0
+	sched_latency = CONFIG_XENO_OPT_TIMING_SCHEDLAT;
+#else /* !CONFIG_XENO_OPT_TIMING_SCHEDLAT */
+	sched_latency = num_online_cpus() > 1 ? 3350 : 2000;
+#endif /* !CONFIG_XENO_OPT_TIMING_SCHEDLAT */
+
+	p->user = sched_latency;
+	p->kernel = CONFIG_XENO_OPT_TIMING_KSCHEDLAT;
+	p->irq = CONFIG_XENO_OPT_TIMING_IRQLAT;
+}
+
+#endif /* !_COBALT_X86_ASM_CALIBRATION_H */
diff --git a/kernel/cobalt/arch/x86/dovetail/include/asm/xenomai/fptest.h b/kernel/cobalt/arch/x86/dovetail/include/asm/xenomai/fptest.h
new file mode 100644
index 0000000000..83a6413d5f
--- /dev/null
+++ b/kernel/cobalt/arch/x86/dovetail/include/asm/xenomai/fptest.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2006 Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org>.
+ *
+ * Xenomai is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2 of the License,
+ * or (at your option) any later version.
+ *
+ * Xenomai is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Xenomai; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+#ifndef _COBALT_X86_ASM_FPTEST_H
+#define _COBALT_X86_ASM_FPTEST_H
+
+#include <linux/errno.h>
+#include <asm/processor.h>
+#include <asm/xenomai/wrappers.h>
+#include <asm/xenomai/uapi/fptest.h>
+
+/*
+ * We do NOT support out-of-band FPU operations in kernel space for a
+ * reason: this is a mess. Out-of-band FPU is just fine and makes a
+ * lot of sense for many real-time applications, but you have to do
+ * that from userland.
+ */
+static inline int fp_kernel_supported(void)
+{
+	return 0;
+}
+
+static inline int fp_linux_begin(void)
+{
+	kernel_fpu_begin();
+	/*
+	 * We need a clean context for testing the sanity of the FPU
+	 * register stack across switches in fp_regs_check()
+	 * (fildl->fistpl), which kernel_fpu_begin() does not
+	 * guarantee us. Force this manually.
+	 */
+	asm volatile("fninit");
+
+	return true;
+}
+
+static inline void fp_linux_end(void)
+{
+	kernel_fpu_end();
+}
+
+static inline int fp_detect(void)
+{
+	int features = 0;
+
+	if (boot_cpu_has(X86_FEATURE_XMM2))
+		features |= __COBALT_HAVE_SSE2;
+
+	if (boot_cpu_has(X86_FEATURE_AVX))
+		features |= __COBALT_HAVE_AVX;
+
+	return features;
+}
+
+#endif /* _COBALT_X86_ASM_FPTEST_H */
diff --git a/kernel/cobalt/arch/x86/dovetail/include/asm/xenomai/machine.h b/kernel/cobalt/arch/x86/dovetail/include/asm/xenomai/machine.h
new file mode 100644
index 0000000000..56b1c4861f
--- /dev/null
+++ b/kernel/cobalt/arch/x86/dovetail/include/asm/xenomai/machine.h
@@ -0,0 +1,34 @@
+/**
+ * Copyright (C) 2007-2012 Philippe Gerum <rpm@xenomai.org>.
+ *
+ * Xenomai is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Xenomai is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Xenomai; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+#ifndef _COBALT_X86_ASM_MACHINE_H
+#define _COBALT_X86_ASM_MACHINE_H
+
+#include <linux/compiler.h>
+
+static inline __attribute_const__ unsigned long ffnz(unsigned long ul)
+{
+	__asm__("bsfq %1, %0":"=r" (ul) : "rm" (ul));
+
+	return ul;
+}
+
+/* Read this last to enable default settings. */
+#include <asm-generic/xenomai/machine.h>
+
+#endif /* !_COBALT_X86_ASM_MACHINE_H */
diff --git a/kernel/cobalt/arch/x86/dovetail/include/asm/xenomai/syscall.h b/kernel/cobalt/arch/x86/dovetail/include/asm/xenomai/syscall.h
new file mode 100644
index 0000000000..c64196b6a1
--- /dev/null
+++ b/kernel/cobalt/arch/x86/dovetail/include/asm/xenomai/syscall.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2001-2014 Philippe Gerum <rpm@xenomai.org>.
+ *
+ * Xenomai is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2 of the License,
+ * or (at your option) any later version.
+ *
+ * Xenomai is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Xenomai; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+#ifndef _COBALT_X86_ASM_SYSCALL_H
+#define _COBALT_X86_ASM_SYSCALL_H
+
+#include <linux/errno.h>
+#include <asm/ptrace.h>
+#include <asm-generic/xenomai/syscall.h>
+
+/*
+ * Cobalt and Linux syscall numbers can be fetched from ORIG_AX,
+ * masking out the __COBALT_SYSCALL_BIT marker.
+ */
+#define __xn_reg_sys(regs)    ((regs)->orig_ax)
+#define __xn_reg_rval(regs)   ((regs)->ax)
+#define __xn_reg_arg1(regs)   ((regs)->di)
+#define __xn_reg_arg2(regs)   ((regs)->si)
+#define __xn_reg_arg3(regs)   ((regs)->dx)
+#define __xn_reg_arg4(regs)   ((regs)->r10)
+#define __xn_reg_arg5(regs)   ((regs)->r8)
+#define __xn_reg_pc(regs)     ((regs)->ip)
+#define __xn_reg_sp(regs)     ((regs)->sp)
+
+#define __xn_syscall_p(regs)  (__xn_reg_sys(regs) & __COBALT_SYSCALL_BIT)
+#ifdef CONFIG_XENO_ARCH_SYS3264
+#define __xn_syscall(regs)    __COBALT_CALL32_SYSNR(__xn_reg_sys(regs)	\
+				    & ~__COBALT_SYSCALL_BIT)
+#else
+#define __xn_syscall(regs)    (__xn_reg_sys(regs) & ~__COBALT_SYSCALL_BIT)
+#endif
+
+#ifdef CONFIG_IA32_EMULATION
+#define __xn_nr_root_syscalls						\
+	({								\
+		struct thread_info *__ti = current_thread_info();	\
+		__ti->status & TS_COMPAT ? IA32_NR_syscalls : NR_syscalls; \
+	})
+#else
+#define __xn_nr_root_syscalls	NR_syscalls
+#endif
+/*
+ * Root syscall number with predicate (valid only if
+ * !__xn_syscall_p(__regs)).
+ */
+#define __xn_rootcall_p(__regs, __code)			\
+	({						\
+		*(__code) = __xn_reg_sys(__regs);	\
+		*(__code) < __xn_nr_root_syscalls;	\
+	})
+
+static inline void __xn_error_return(struct pt_regs *regs, int v)
+{
+	__xn_reg_rval(regs) = v;
+}
+
+static inline void __xn_status_return(struct pt_regs *regs, long v)
+{
+	__xn_reg_rval(regs) = v;
+}
+
+static inline int __xn_interrupted_p(struct pt_regs *regs)
+{
+	return __xn_reg_rval(regs) == -EINTR;
+}
+
+static inline
+int xnarch_local_syscall(unsigned long a1, unsigned long a2,
+			 unsigned long a3, unsigned long a4,
+			 unsigned long a5)
+{
+	return -ENOSYS;
+}
+
+#endif /* !_COBALT_X86_ASM_SYSCALL_H */
diff --git a/kernel/cobalt/arch/x86/dovetail/include/asm/xenomai/thread.h b/kernel/cobalt/arch/x86/dovetail/include/asm/xenomai/thread.h
new file mode 100644
index 0000000000..73ecd945cd
--- /dev/null
+++ b/kernel/cobalt/arch/x86/dovetail/include/asm/xenomai/thread.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2001-2013 Philippe Gerum <rpm@xenomai.org>.
+ * Copyright (C) 2004-2006 Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org>.
+ *
+ * Xenomai is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Xenomai is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Xenomai; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+#ifndef _COBALT_X86_ASM_THREAD_H
+#define _COBALT_X86_ASM_THREAD_H
+
+#include <linux/dovetail.h>
+#include <asm-generic/xenomai/thread.h>
+#include <asm/traps.h>
+
+struct xnarchtcb {
+	struct xntcb core;
+	struct dovetail_altsched_context altsched;
+};
+
+#define xnarch_fault_pc(__regs)		((__regs)->ip)
+#define xnarch_fault_pf_p(__nr)		((__nr) == X86_TRAP_PF)
+#define xnarch_fault_bp_p(__nr)		((current->ptrace & PT_PTRACED) &&	\
+					 ((__nr) == X86_TRAP_DB || (__nr) == X86_TRAP_BP))
+#define xnarch_fault_notify(__nr)	(!xnarch_fault_bp_p(__nr))
+
+#endif /* !_COBALT_X86_ASM_THREAD_H */
diff --git a/kernel/cobalt/arch/x86/dovetail/machine.c b/kernel/cobalt/arch/x86/dovetail/machine.c
new file mode 100644
index 0000000000..562de40dcb
--- /dev/null
+++ b/kernel/cobalt/arch/x86/dovetail/machine.c
@@ -0,0 +1,70 @@
+/**
+ *   Copyright (C) 2007-2012 Philippe Gerum.
+ *
+ *   Xenomai is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License as
+ *   published by the Free Software Foundation, Inc., 675 Mass Ave,
+ *   Cambridge MA 02139, USA; either version 2 of the License, or (at
+ *   your option) any later version.
+ *
+ *   Xenomai is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *   General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ *   02111-1307, USA.
+ */
+
+#include <asm/xenomai/machine.h>
+#include <asm/xenomai/smi.h>
+#include <asm/xenomai/c1e.h>
+
+static int mach_x86_init(void)
+{
+	mach_x86_c1e_disable();
+	mach_x86_smi_init();
+	mach_x86_smi_disable();
+
+	return 0;
+}
+
+static void mach_x86_cleanup(void)
+{
+	mach_x86_smi_restore();
+}
+
+static const char *const fault_labels[] = {
+    [0] = "Divide error",
+    [1] = "Debug",
+    [2] = "",   /* NMI is not pipelined. */
+    [3] = "Int3",
+    [4] = "Overflow",
+    [5] = "Bounds",
+    [6] = "Invalid opcode",
+    [7] = "FPU not available",
+    [8] = "Double fault",
+    [9] = "FPU segment overrun",
+    [10] = "Invalid TSS",
+    [11] = "Segment not present",
+    [12] = "Stack segment",
+    [13] = "General protection",
+    [14] = "Page fault",
+    [15] = "Spurious interrupt",
+    [16] = "FPU error",
+    [17] = "Alignment check",
+    [18] = "Machine check",
+    [19] = "SIMD error",
+    [20] = NULL,
+};
+
+struct cobalt_machine cobalt_machine = {
+	.name = "x86",
+	.init = mach_x86_init,
+	.late_init = NULL,
+	.cleanup = mach_x86_cleanup,
+	.prefault = NULL,
+	.fault_labels = fault_labels,
+};
diff --git a/kernel/cobalt/arch/x86/dovetail/smi.c b/kernel/cobalt/arch/x86/dovetail/smi.c
new file mode 120000
index 0000000000..8d197210f4
--- /dev/null
+++ b/kernel/cobalt/arch/x86/dovetail/smi.c
@@ -0,0 +1 @@
+../ipipe/smi.c
\ No newline at end of file
diff --git a/kernel/cobalt/arch/x86/ipipe/smi.c b/kernel/cobalt/arch/x86/ipipe/smi.c
index 7f7c9fd135..f28af9a3b5 100644
--- a/kernel/cobalt/arch/x86/ipipe/smi.c
+++ b/kernel/cobalt/arch/x86/ipipe/smi.c
@@ -109,7 +109,7 @@ static const char *smi_state_labels[] = {
 	"detect",
 	"enabled",
 };
-	
+
 static void setup_smi_state(void)
 {
 	static char warn_bad_state[] =
@@ -147,7 +147,7 @@ void mach_x86_smi_init(void)
 	 * Just register the used ports.
 	 */
 	dev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL);
-	if (dev == NULL || dev->bus->number || 
+	if (dev == NULL || dev->bus->number ||
 	    dev->devfn != DEVFN || dev->vendor != PCI_VENDOR_ID_INTEL) {
 		pci_dev_put(dev);
 		return;
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 10/25] cobalt/kernel: dovetail: implement sirq services
  2021-05-20 21:44 [PATCH 00/25] Dovetail integration, next round Jan Kiszka
                   ` (8 preceding siblings ...)
  2021-05-20 21:44 ` [PATCH 09/25] cobalt/x86: dovetail: add architecture bits Jan Kiszka
@ 2021-05-20 21:44 ` Jan Kiszka
  2021-05-20 21:44 ` [PATCH 11/25] cobalt/sched: dovetail: add task control block initializers Jan Kiszka
                   ` (14 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Jan Kiszka @ 2021-05-20 21:44 UTC (permalink / raw)
  To: xenomai

From: Hongzhan Chen <hongzhan.chen@intel.com>

inband sirq request through synthetic_irq_domain and free and post
srq.

Signed-off-by: Hongzhan Chen <hongzhan.chen@intel.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 .../cobalt/kernel/dovetail/pipeline/sirq.h    | 28 +++++++++++++++----
 1 file changed, 23 insertions(+), 5 deletions(-)

diff --git a/include/cobalt/kernel/dovetail/pipeline/sirq.h b/include/cobalt/kernel/dovetail/pipeline/sirq.h
index be9dc587fb..1da9d13b21 100644
--- a/include/cobalt/kernel/dovetail/pipeline/sirq.h
+++ b/include/cobalt/kernel/dovetail/pipeline/sirq.h
@@ -23,9 +23,24 @@ int pipeline_create_inband_sirq(irqreturn_t (*handler)(int irq, void *dev_id))
 	 * Allocate an IRQ from the synthetic interrupt domain then
 	 * trap it to @handler, to be fired from the in-band stage.
 	 */
-	TODO();
+	int sirq, ret;
 
-	return 0;
+	sirq = irq_create_direct_mapping(synthetic_irq_domain);
+	if (sirq == 0)
+		return -EAGAIN;
+
+	ret = __request_percpu_irq(sirq,
+			handler,
+			IRQF_NO_THREAD,
+			"Inband sirq",
+			&cobalt_machine_cpudata);
+
+	if (ret) {
+		irq_dispose_mapping(sirq);
+		return ret;
+	}
+
+	return sirq;
 }
 
 static inline
@@ -35,13 +50,16 @@ void pipeline_delete_inband_sirq(int sirq)
 	 * Free the synthetic IRQ then deallocate it to its
 	 * originating domain.
 	 */
-	TODO();
+	free_percpu_irq(sirq,
+		&cobalt_machine_cpudata);
+
+	irq_dispose_mapping(sirq);
 }
 
 static inline void pipeline_post_sirq(int sirq)
 {
 	/* Trigger the synthetic IRQ */
-	TODO();
+	irq_post_inband(sirq);
 }
 
-#endif /* !_COBALT_KERNEL_IPIPE_SIRQ_H */
+#endif /* !_COBALT_KERNEL_DOVETAIL_SIRQ_H */
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 11/25] cobalt/sched: dovetail: add task control block initializers
  2021-05-20 21:44 [PATCH 00/25] Dovetail integration, next round Jan Kiszka
                   ` (9 preceding siblings ...)
  2021-05-20 21:44 ` [PATCH 10/25] cobalt/kernel: dovetail: implement sirq services Jan Kiszka
@ 2021-05-20 21:44 ` Jan Kiszka
  2021-05-20 21:44 ` [PATCH 12/25] cobalt/clock: dovetail: provide backend code to CLOCK_HOST_REALTIME Jan Kiszka
                   ` (13 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Jan Kiszka @ 2021-05-20 21:44 UTC (permalink / raw)
  To: xenomai

From: Hongzhan Chen <hongzhan.chen@intel.com>

Signed-off-by: Hongzhan Chen <hongzhan.chen@intel.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 kernel/cobalt/dovetail/sched.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cobalt/dovetail/sched.c b/kernel/cobalt/dovetail/sched.c
index 71f763d399..82e29136ca 100644
--- a/kernel/cobalt/dovetail/sched.c
+++ b/kernel/cobalt/dovetail/sched.c
@@ -36,7 +36,7 @@ void pipeline_init_shadow_tcb(struct xnthread *thread)
 	/*
 	 * Initialize the alternate scheduling control block.
 	 */
-	TODO();
+	dovetail_init_altsched(&xnthread_archtcb(thread)->altsched);
 
 	trace_cobalt_shadow_map(thread);
 }
@@ -46,7 +46,7 @@ void pipeline_init_root_tcb(struct xnthread *thread)
 	/*
 	 * Initialize the alternate scheduling control block.
 	 */
-	TODO();
+	dovetail_init_altsched(&xnthread_archtcb(thread)->altsched);
 }
 
 int pipeline_leave_inband(void)
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 12/25] cobalt/clock: dovetail: provide backend code to CLOCK_HOST_REALTIME
  2021-05-20 21:44 [PATCH 00/25] Dovetail integration, next round Jan Kiszka
                   ` (10 preceding siblings ...)
  2021-05-20 21:44 ` [PATCH 11/25] cobalt/sched: dovetail: add task control block initializers Jan Kiszka
@ 2021-05-20 21:44 ` Jan Kiszka
  2021-05-20 21:44 ` [PATCH 13/25] cobalt/init: dovetail: add oob stage enabling, disabling services Jan Kiszka
                   ` (12 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Jan Kiszka @ 2021-05-20 21:44 UTC (permalink / raw)
  To: xenomai

From: Hongzhan Chen <hongzhan.chen@intel.com>

Signed-off-by: Hongzhan Chen <hongzhan.chen@intel.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 include/cobalt/kernel/dovetail/pipeline/clock.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/include/cobalt/kernel/dovetail/pipeline/clock.h b/include/cobalt/kernel/dovetail/pipeline/clock.h
index 19e3d89865..1cd7530655 100644
--- a/include/cobalt/kernel/dovetail/pipeline/clock.h
+++ b/include/cobalt/kernel/dovetail/pipeline/clock.h
@@ -7,6 +7,7 @@
 
 #include <cobalt/uapi/kernel/types.h>
 #include <cobalt/kernel/assert.h>
+#include <linux/ktime.h>
 
 struct timespec64;
 
@@ -52,7 +53,7 @@ static inline const char *pipeline_clock_name(void)
 static inline int pipeline_get_host_time(struct timespec64 *tp)
 {
 	/* Convert ktime_get_real_fast_ns() to timespec. */
-	TODO();
+	*tp = ktime_to_timespec64(ktime_get_real_fast_ns());
 
 	return 0;
 }
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 13/25] cobalt/init: dovetail: add oob stage enabling, disabling services
  2021-05-20 21:44 [PATCH 00/25] Dovetail integration, next round Jan Kiszka
                   ` (11 preceding siblings ...)
  2021-05-20 21:44 ` [PATCH 12/25] cobalt/clock: dovetail: provide backend code to CLOCK_HOST_REALTIME Jan Kiszka
@ 2021-05-20 21:44 ` Jan Kiszka
  2021-05-20 21:44 ` [PATCH 14/25] cobalt/timer: Check if nklock is held in timer services Jan Kiszka
                   ` (11 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Jan Kiszka @ 2021-05-20 21:44 UTC (permalink / raw)
  To: xenomai

From: Hongzhan Chen <hongzhan.chen@intel.com>

Signed-off-by: Hongzhan Chen <hongzhan.chen@intel.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 kernel/cobalt/dovetail/init.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/cobalt/dovetail/init.c b/kernel/cobalt/dovetail/init.c
index 983186abe1..bc891b4c13 100644
--- a/kernel/cobalt/dovetail/init.c
+++ b/kernel/cobalt/dovetail/init.c
@@ -20,7 +20,7 @@ int __init pipeline_init(void)
 	}
 
 	/* Enable the Xenomai out-of-band stage */
-	TODO();
+	enable_oob_stage("Xenomai");
 
 	ret = xnclock_init();
 	if (ret)
@@ -46,7 +46,7 @@ int __init pipeline_late_init(void)
 __init void pipeline_cleanup(void)
 {
 	/* Disable the Xenomai stage */
-	TODO();
+	disable_oob_stage();
 
 	xnclock_cleanup();
 }
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 14/25] cobalt/timer: Check if nklock is held in timer services
  2021-05-20 21:44 [PATCH 00/25] Dovetail integration, next round Jan Kiszka
                   ` (12 preceding siblings ...)
  2021-05-20 21:44 ` [PATCH 13/25] cobalt/init: dovetail: add oob stage enabling, disabling services Jan Kiszka
@ 2021-05-20 21:44 ` Jan Kiszka
  2021-05-20 21:44 ` [PATCH 15/25] cobalt/tick: dovetail: install/uninstall proxy tick device Jan Kiszka
                   ` (10 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Jan Kiszka @ 2021-05-20 21:44 UTC (permalink / raw)
  To: xenomai

From: Philippe Gerum <rpm@xenomai.org>

Signed-off-by: Philippe Gerum <rpm@xenomai.org>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 kernel/cobalt/timer.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/kernel/cobalt/timer.c b/kernel/cobalt/timer.c
index f9aa457ce9..9297cca186 100644
--- a/kernel/cobalt/timer.c
+++ b/kernel/cobalt/timer.c
@@ -118,6 +118,8 @@ int xntimer_start(struct xntimer *timer,
 	unsigned long gravity;
 	int ret = 0;
 
+	atomic_only();
+
 	trace_cobalt_timer_start(timer, value, interval, mode);
 
 	if ((timer->status & XNTIMER_DEQUEUED) == 0)
@@ -204,6 +206,8 @@ void __xntimer_stop(struct xntimer *timer)
 	struct xnsched *sched;
 	int heading = 1;
 
+	atomic_only();
+
 	trace_cobalt_timer_stop(timer);
 
 	if ((timer->status & XNTIMER_DEQUEUED) == 0) {
@@ -239,6 +243,8 @@ EXPORT_SYMBOL_GPL(__xntimer_stop);
  */
 xnticks_t xntimer_get_date(struct xntimer *timer)
 {
+	atomic_only();
+
 	if (!xntimer_running_p(timer))
 		return XN_INFINITE;
 
@@ -269,6 +275,8 @@ xnticks_t __xntimer_get_timeout(struct xntimer *timer)
 	struct xnclock *clock;
 	xnticks_t expiry, now;
 
+	atomic_only();
+
 	clock = xntimer_clock(timer);
 	now = xnclock_read_raw(clock);
 	expiry = xntimer_expiry(timer);
@@ -431,6 +439,8 @@ void __xntimer_switch_tracking(struct xntimer *timer,
 void xntimer_set_clock(struct xntimer *timer,
 		       struct xnclock *newclock)
 {
+	atomic_only();
+
 	if (timer->clock != newclock) {
 		xntimer_stop(timer);
 		timer->clock = newclock;
@@ -605,6 +615,8 @@ unsigned long long xntimer_get_overruns(struct xntimer *timer,
 	xnsticks_t delta;
 	xntimerq_t *q;
 
+	atomic_only();
+
 	delta = now - xntimer_pexpect(timer);
 	if (unlikely(delta >= (xnsticks_t) period)) {
 		period = timer->interval_ns;
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 15/25] cobalt/tick: dovetail: install/uninstall proxy tick device
  2021-05-20 21:44 [PATCH 00/25] Dovetail integration, next round Jan Kiszka
                   ` (13 preceding siblings ...)
  2021-05-20 21:44 ` [PATCH 14/25] cobalt/timer: Check if nklock is held in timer services Jan Kiszka
@ 2021-05-20 21:44 ` Jan Kiszka
  2021-05-20 21:44 ` [PATCH 16/25] cobalt/tick: dovetail: implement pipeline_set_timer_shot() Jan Kiszka
                   ` (9 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Jan Kiszka @ 2021-05-20 21:44 UTC (permalink / raw)
  To: xenomai

From: Hongzhan Chen <hongzhan.chen@intel.com>

Signed-off-by: Hongzhan Chen <hongzhan.chen@intel.com>
[Philippe: protect xntimer_start with nklock]
Signed-off-by: Philippe Gerum <rpm@xenomai.org>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 kernel/cobalt/dovetail/tick.c | 83 ++++++++++++++++++++++++++++++++++-
 1 file changed, 81 insertions(+), 2 deletions(-)

diff --git a/kernel/cobalt/dovetail/tick.c b/kernel/cobalt/dovetail/tick.c
index 01927f7089..fba9f78d00 100644
--- a/kernel/cobalt/dovetail/tick.c
+++ b/kernel/cobalt/dovetail/tick.c
@@ -6,8 +6,87 @@
  */
 
 #include <linux/tick.h>
+#include <linux/clockchips.h>
 #include <cobalt/kernel/intr.h>
 #include <pipeline/tick.h>
+#include <cobalt/kernel/sched.h>
+#include <cobalt/kernel/timer.h>
+
+static DEFINE_PER_CPU(struct clock_proxy_device *, proxy_device);
+
+static int proxy_set_next_ktime(ktime_t expires,
+				struct clock_event_device *proxy_dev)
+{
+	struct xnsched *sched;
+	ktime_t delta;
+	unsigned long flags;
+	int ret;
+
+	/*
+	 * When Negative delta have been observed, we set delta zero.
+	 * Or else exntimer_start() will return -ETIMEDOUT and do not
+	 * trigger shot
+	 */
+	delta = ktime_sub(expires, ktime_get_mono_fast_ns());
+	if (delta < 0)
+		delta = 0;
+
+	xnlock_get_irqsave(&nklock, flags);
+	sched = xnsched_current();
+	ret = xntimer_start(&sched->htimer, delta, XN_INFINITE, XN_RELATIVE);
+	xnlock_put_irqrestore(&nklock, flags);
+
+	return ret ? -ETIME : 0;
+}
+
+void xn_core_tick(struct clock_event_device *dummy) /* hard irqs off */
+{
+	xnintr_core_clock_handler();
+}
+
+static int proxy_set_oneshot_stopped(struct clock_event_device *proxy_dev)
+{
+	struct clock_event_device *real_dev;
+	struct clock_proxy_device *dev;
+	struct xnsched *sched;
+	spl_t s;
+
+	dev = container_of(proxy_dev, struct clock_proxy_device, proxy_device);
+
+	/*
+	 * In-band wants to disable the clock hardware on entering a
+	 * tickless state, so we have to stop our in-band tick
+	 * emulation. Propagate the request for shutting down the
+	 * hardware to the real device only if we have no outstanding
+	 * OOB timers. CAUTION: the in-band timer is counted when
+	 * assessing the RQ_IDLE condition, so we need to stop it
+	 * prior to testing the latter.
+	 */
+	xnlock_get_irqsave(&nklock, s);
+	sched = xnsched_current();
+	xntimer_stop(&sched->htimer);
+
+	if (sched->lflags & XNIDLE) {
+		real_dev = dev->real_device;
+		real_dev->set_state_oneshot_stopped(real_dev);
+	}
+
+	xnlock_put_irqrestore(&nklock, s);
+
+	return 0;
+}
+
+static void setup_proxy(struct clock_proxy_device *dev)
+{
+	struct clock_event_device *proxy_dev = &dev->proxy_device;
+
+	dev->handle_oob_event = xn_core_tick;
+	proxy_dev->features |= CLOCK_EVT_FEAT_KTIME;
+	proxy_dev->set_next_ktime = proxy_set_next_ktime;
+	if (proxy_dev->set_state_oneshot_stopped)
+		proxy_dev->set_state_oneshot_stopped = proxy_set_oneshot_stopped;
+	__this_cpu_write(proxy_device, dev);
+}
 
 int pipeline_install_tick_proxy(void)
 {
@@ -18,7 +97,7 @@ int pipeline_install_tick_proxy(void)
 		return ret;
 
 	/* Install the proxy tick device */
-	TODO();	ret = 0;
+	ret = tick_install_proxy(setup_proxy, &xnsched_realtime_cpus);
 	if (ret)
 		goto fail_proxy;
 
@@ -33,7 +112,7 @@ fail_proxy:
 void pipeline_uninstall_tick_proxy(void)
 {
 	/* Uninstall the proxy tick device. */
-	TODO();
+	tick_uninstall_proxy(&xnsched_realtime_cpus);
 
 	pipeline_free_timer_ipi();
 }
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 16/25] cobalt/tick: dovetail: implement pipeline_set_timer_shot()
  2021-05-20 21:44 [PATCH 00/25] Dovetail integration, next round Jan Kiszka
                   ` (14 preceding siblings ...)
  2021-05-20 21:44 ` [PATCH 15/25] cobalt/tick: dovetail: install/uninstall proxy tick device Jan Kiszka
@ 2021-05-20 21:44 ` Jan Kiszka
  2021-05-20 21:44 ` [PATCH 17/25] cobalt/tick: dovetail: implement pipeline_timer_name() Jan Kiszka
                   ` (8 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Jan Kiszka @ 2021-05-20 21:44 UTC (permalink / raw)
  To: xenomai

From: Hongzhan Chen <hongzhan.chen@intel.com>

Signed-off-by: Hongzhan Chen <hongzhan.chen@intel.com>
[Philippe: clarify some variable names]
Signed-off-by: Philippe Gerum <rpm@xenomai.org>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 .../cobalt/kernel/dovetail/pipeline/clock.h   | 12 +-------
 kernel/cobalt/dovetail/tick.c                 | 28 +++++++++++++++++++
 2 files changed, 29 insertions(+), 11 deletions(-)

diff --git a/include/cobalt/kernel/dovetail/pipeline/clock.h b/include/cobalt/kernel/dovetail/pipeline/clock.h
index 1cd7530655..d5443a4fd6 100644
--- a/include/cobalt/kernel/dovetail/pipeline/clock.h
+++ b/include/cobalt/kernel/dovetail/pipeline/clock.h
@@ -19,17 +19,7 @@ static inline u64 pipeline_read_cycle_counter(void)
 	return 0;
 }
 
-static inline void pipeline_set_timer_shot(unsigned long cycles)
-{
-	/*
-	 * N/A. Revisit: xnclock_core_local_shot() should go to the
-	 * I-pipe section, we do things differently on Dovetail via
-	 * the proxy tick device. As a consequence,
-	 * pipeline_set_timer_shot() should not be part of the
-	 * pipeline interface.
-	 */
-	TODO();
-}
+void pipeline_set_timer_shot(unsigned long cycles);
 
 static inline const char *pipeline_timer_name(void)
 {
diff --git a/kernel/cobalt/dovetail/tick.c b/kernel/cobalt/dovetail/tick.c
index fba9f78d00..a6633348b1 100644
--- a/kernel/cobalt/dovetail/tick.c
+++ b/kernel/cobalt/dovetail/tick.c
@@ -14,6 +14,34 @@
 
 static DEFINE_PER_CPU(struct clock_proxy_device *, proxy_device);
 
+void pipeline_set_timer_shot(unsigned long delay) /* ns */
+{
+	struct clock_proxy_device *dev = __this_cpu_read(proxy_device);
+	struct clock_event_device *real_dev = dev->real_device;
+	u64 cycles;
+	ktime_t t;
+	int ret;
+
+	if (real_dev->features & CLOCK_EVT_FEAT_KTIME) {
+		t = ktime_add(delay, xnclock_core_read_raw());
+		real_dev->set_next_ktime(t, real_dev);
+	} else {
+		if (delay <= 0) {
+			delay = real_dev->min_delta_ns;
+		} else {
+			delay = min_t(int64_t, delay,
+				real_dev->max_delta_ns);
+			delay = max_t(int64_t, delay,
+				real_dev->min_delta_ns);
+		}
+		cycles = ((u64)delay * real_dev->mult) >> real_dev->shift;
+		ret = real_dev->set_next_event(cycles, real_dev);
+		if (ret)
+			real_dev->set_next_event(real_dev->min_delta_ticks,
+						real_dev);
+	}
+}
+
 static int proxy_set_next_ktime(ktime_t expires,
 				struct clock_event_device *proxy_dev)
 {
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 17/25] cobalt/tick: dovetail: implement pipeline_timer_name()
  2021-05-20 21:44 [PATCH 00/25] Dovetail integration, next round Jan Kiszka
                   ` (15 preceding siblings ...)
  2021-05-20 21:44 ` [PATCH 16/25] cobalt/tick: dovetail: implement pipeline_set_timer_shot() Jan Kiszka
@ 2021-05-20 21:44 ` Jan Kiszka
  2021-05-20 21:44 ` [PATCH 18/25] cobalt/timer: pipeline: abstract handling of ONESHOT_STOPPED mode Jan Kiszka
                   ` (7 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Jan Kiszka @ 2021-05-20 21:44 UTC (permalink / raw)
  To: xenomai

From: Hongzhan Chen <hongzhan.chen@intel.com>

Get the name of real device controlled by the proxy tick device.

Signed-off-by: Hongzhan Chen <hongzhan.chen@intel.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 include/cobalt/kernel/dovetail/pipeline/clock.h | 11 +----------
 kernel/cobalt/dovetail/tick.c                   | 12 ++++++++++++
 2 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/include/cobalt/kernel/dovetail/pipeline/clock.h b/include/cobalt/kernel/dovetail/pipeline/clock.h
index d5443a4fd6..82f02d4d77 100644
--- a/include/cobalt/kernel/dovetail/pipeline/clock.h
+++ b/include/cobalt/kernel/dovetail/pipeline/clock.h
@@ -21,16 +21,7 @@ static inline u64 pipeline_read_cycle_counter(void)
 
 void pipeline_set_timer_shot(unsigned long cycles);
 
-static inline const char *pipeline_timer_name(void)
-{
-	/*
-	 * Return the name of the current clock event chip, which is
-	 * the real device controlled by the proxy tick device.
-	 */
-	TODO();
-
-	return "?";
-}
+const char *pipeline_timer_name(void);
 
 static inline const char *pipeline_clock_name(void)
 {
diff --git a/kernel/cobalt/dovetail/tick.c b/kernel/cobalt/dovetail/tick.c
index a6633348b1..41aaa151a8 100644
--- a/kernel/cobalt/dovetail/tick.c
+++ b/kernel/cobalt/dovetail/tick.c
@@ -14,6 +14,18 @@
 
 static DEFINE_PER_CPU(struct clock_proxy_device *, proxy_device);
 
+const char *pipeline_timer_name(void)
+{
+	struct clock_proxy_device *dev = __this_cpu_read(proxy_device);
+	struct clock_event_device *real_dev = dev->real_device;
+
+	/*
+	 * Return the name of the current clock event chip, which is
+	 * the real device controlled by the proxy tick device.
+	 */
+	return real_dev->name;
+}
+
 void pipeline_set_timer_shot(unsigned long delay) /* ns */
 {
 	struct clock_proxy_device *dev = __this_cpu_read(proxy_device);
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 18/25] cobalt/timer: pipeline: abstract handling of ONESHOT_STOPPED mode
  2021-05-20 21:44 [PATCH 00/25] Dovetail integration, next round Jan Kiszka
                   ` (16 preceding siblings ...)
  2021-05-20 21:44 ` [PATCH 17/25] cobalt/tick: dovetail: implement pipeline_timer_name() Jan Kiszka
@ 2021-05-20 21:44 ` Jan Kiszka
  2021-05-20 21:44 ` [PATCH 19/25] cobalt/timer: dovetail: handle " Jan Kiszka
                   ` (6 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Jan Kiszka @ 2021-05-20 21:44 UTC (permalink / raw)
  To: xenomai

From: Hongzhan Chen <hongzhan.chen@intel.com>

It adds a way to force the timer management code to reprogram the
hardware on option, to make the real device controlled by the proxy
tick again as it leaves the ONESHOT_STOPPED mode. The I-pipe does not
require any further action in this case, leading to a nop.

Signed-off-by: Hongzhan Chen <hongzhan.chen@intel.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 include/cobalt/kernel/ipipe/pipeline/tick.h | 6 ++++++
 include/cobalt/kernel/sched.h               | 5 +++++
 kernel/cobalt/clock.c                       | 2 +-
 kernel/cobalt/timer.c                       | 5 ++++-
 4 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/include/cobalt/kernel/ipipe/pipeline/tick.h b/include/cobalt/kernel/ipipe/pipeline/tick.h
index 409581a3cb..41347f7b18 100644
--- a/include/cobalt/kernel/ipipe/pipeline/tick.h
+++ b/include/cobalt/kernel/ipipe/pipeline/tick.h
@@ -9,4 +9,10 @@ int pipeline_install_tick_proxy(void);
 
 void pipeline_uninstall_tick_proxy(void);
 
+struct xnsched;
+static inline bool pipeline_must_force_program_tick(struct xnsched *sched)
+{
+	return false;
+}
+
 #endif /* !_COBALT_KERNEL_IPIPE_TICK_H */
diff --git a/include/cobalt/kernel/sched.h b/include/cobalt/kernel/sched.h
index c13f46ff7d..aa24d54420 100644
--- a/include/cobalt/kernel/sched.h
+++ b/include/cobalt/kernel/sched.h
@@ -48,6 +48,11 @@
 #define XNINIRQ		0x00004000	/* In IRQ handling context */
 #define XNHDEFER	0x00002000	/* Host tick deferred */
 
+/*
+ * Hardware timer is stopped.
+ */
+#define XNTSTOP		0x00000800
+
 struct xnsched_rt {
 	xnsched_queue_t runnable;	/*!< Runnable thread queue. */
 };
diff --git a/kernel/cobalt/clock.c b/kernel/cobalt/clock.c
index bf24e16938..2115b15ef8 100644
--- a/kernel/cobalt/clock.c
+++ b/kernel/cobalt/clock.c
@@ -147,7 +147,7 @@ void xnclock_core_local_shot(struct xnsched *sched)
 	 * or a timer with an earlier timeout date is scheduled,
 	 * whichever comes first.
 	 */
-	sched->lflags &= ~(XNHDEFER|XNIDLE);
+	sched->lflags &= ~(XNHDEFER|XNIDLE|XNTSTOP);
 	timer = container_of(h, struct xntimer, aplink);
 	if (unlikely(timer == &sched->htimer)) {
 		if (xnsched_resched_p(sched) ||
diff --git a/kernel/cobalt/timer.c b/kernel/cobalt/timer.c
index 9297cca186..1ec7617915 100644
--- a/kernel/cobalt/timer.c
+++ b/kernel/cobalt/timer.c
@@ -18,6 +18,7 @@
  * 02111-1307, USA.
  */
 #include <linux/sched.h>
+#include <pipeline/tick.h>
 #include <cobalt/kernel/sched.h>
 #include <cobalt/kernel/thread.h>
 #include <cobalt/kernel/timer.h>
@@ -63,8 +64,10 @@ int xntimer_heading_p(struct xntimer *timer)
 
 void xntimer_enqueue_and_program(struct xntimer *timer, xntimerq_t *q)
 {
+	struct xnsched *sched = xntimer_sched(timer);
+
 	xntimer_enqueue(timer, q);
-	if (xntimer_heading_p(timer)) {
+	if (pipeline_must_force_program_tick(sched) || xntimer_heading_p(timer)) {
 		struct xnsched *sched = xntimer_sched(timer);
 		struct xnclock *clock = xntimer_clock(timer);
 		if (sched != xnsched_current())
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 19/25] cobalt/timer: dovetail: handle ONESHOT_STOPPED mode
  2021-05-20 21:44 [PATCH 00/25] Dovetail integration, next round Jan Kiszka
                   ` (17 preceding siblings ...)
  2021-05-20 21:44 ` [PATCH 18/25] cobalt/timer: pipeline: abstract handling of ONESHOT_STOPPED mode Jan Kiszka
@ 2021-05-20 21:44 ` Jan Kiszka
  2021-05-20 21:44 ` [PATCH 20/25] cobalt/tick: dovetail: flatten the call stack to pipeline services Jan Kiszka
                   ` (5 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Jan Kiszka @ 2021-05-20 21:44 UTC (permalink / raw)
  To: xenomai

From: Hongzhan Chen <hongzhan.chen@intel.com>

Force the next tick to be programmed in the hardware as a result of
leaving the ONESHOT_STOPPED

Signed-off-by: Hongzhan Chen <hongzhan.chen@intel.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 include/cobalt/kernel/dovetail/pipeline/tick.h | 4 ++++
 kernel/cobalt/dovetail/tick.c                  | 6 ++++++
 2 files changed, 10 insertions(+)

diff --git a/include/cobalt/kernel/dovetail/pipeline/tick.h b/include/cobalt/kernel/dovetail/pipeline/tick.h
index 409581a3cb..8ac4760ecd 100644
--- a/include/cobalt/kernel/dovetail/pipeline/tick.h
+++ b/include/cobalt/kernel/dovetail/pipeline/tick.h
@@ -9,4 +9,8 @@ int pipeline_install_tick_proxy(void);
 
 void pipeline_uninstall_tick_proxy(void);
 
+struct xnsched;
+
+inline bool pipeline_must_force_program_tick(struct xnsched *sched);
+
 #endif /* !_COBALT_KERNEL_IPIPE_TICK_H */
diff --git a/kernel/cobalt/dovetail/tick.c b/kernel/cobalt/dovetail/tick.c
index 41aaa151a8..502ec27b22 100644
--- a/kernel/cobalt/dovetail/tick.c
+++ b/kernel/cobalt/dovetail/tick.c
@@ -84,6 +84,11 @@ void xn_core_tick(struct clock_event_device *dummy) /* hard irqs off */
 	xnintr_core_clock_handler();
 }
 
+inline bool pipeline_must_force_program_tick(struct xnsched *sched)
+{
+	return sched->lflags & XNTSTOP;
+}
+
 static int proxy_set_oneshot_stopped(struct clock_event_device *proxy_dev)
 {
 	struct clock_event_device *real_dev;
@@ -105,6 +110,7 @@ static int proxy_set_oneshot_stopped(struct clock_event_device *proxy_dev)
 	xnlock_get_irqsave(&nklock, s);
 	sched = xnsched_current();
 	xntimer_stop(&sched->htimer);
+	sched->lflags |= XNTSTOP;
 
 	if (sched->lflags & XNIDLE) {
 		real_dev = dev->real_device;
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 20/25] cobalt/tick: dovetail: flatten the call stack to pipeline services
  2021-05-20 21:44 [PATCH 00/25] Dovetail integration, next round Jan Kiszka
                   ` (18 preceding siblings ...)
  2021-05-20 21:44 ` [PATCH 19/25] cobalt/timer: dovetail: handle " Jan Kiszka
@ 2021-05-20 21:44 ` Jan Kiszka
  2021-05-20 21:44 ` [PATCH 21/25] cobalt/clock: dovetail: implement pipeline_read_cycle_counter() Jan Kiszka
                   ` (4 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Jan Kiszka @ 2021-05-20 21:44 UTC (permalink / raw)
  To: xenomai

From: Philippe Gerum <rpm@xenomai.org>

Since we are dealing with pipeline specific code, we may flatten the
call stack by using the Dovetail API directly.

Signed-off-by: Philippe Gerum <rpm@xenomai.org>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 .../kernel/dovetail/pipeline/pipeline.h       | 43 +------------------
 kernel/cobalt/dovetail/sched.c                |  8 ++++
 kernel/cobalt/dovetail/tick.c                 | 26 ++++++-----
 3 files changed, 26 insertions(+), 51 deletions(-)

diff --git a/include/cobalt/kernel/dovetail/pipeline/pipeline.h b/include/cobalt/kernel/dovetail/pipeline/pipeline.h
index bbd45d13b3..3cc7268d00 100644
--- a/include/cobalt/kernel/dovetail/pipeline/pipeline.h
+++ b/include/cobalt/kernel/dovetail/pipeline/pipeline.h
@@ -12,8 +12,6 @@
 
 typedef unsigned long spl_t;
 
-void xnintr_core_clock_handler(void);
-
 /*
  * We only keep the LSB when testing in SMP mode in order to strip off
  * the recursion marker (0x2) the nklock may store there.
@@ -33,19 +31,13 @@ void xnintr_core_clock_handler(void);
 
 #ifdef CONFIG_SMP
 
-static irqreturn_t reschedule_interrupt_handler(int irq, void *dev_id)
-{
-
-	/* Will reschedule from irq_exit_pipeline. */
-
-	return IRQ_HANDLED;
-}
+irqreturn_t pipeline_reschedule_ipi_handler(int irq, void *dev_id);
 
 static inline int pipeline_request_resched_ipi(void (*handler)(void))
 {
 	/* Trap the out-of-band rescheduling interrupt. */
 	return __request_percpu_irq(RESCHEDULE_OOB_IPI,
-			reschedule_interrupt_handler,
+			pipeline_reschedule_ipi_handler,
 			IRQF_OOB,
 			"Xenomai reschedule",
 			&cobalt_machine_cpudata);
@@ -66,28 +58,6 @@ static inline void pipeline_send_resched_ipi(const struct cpumask *dest)
 	irq_send_oob_ipi(RESCHEDULE_OOB_IPI, dest);
 }
 
-static irqreturn_t timer_ipi_interrupt_handler(int irq, void *dev_id)
-{
-	xnintr_core_clock_handler();
-
-	return IRQ_HANDLED;
-}
-
-static inline int pipeline_request_timer_ipi(void (*handler)(void))
-{
-	/* Trap the out-of-band timer interrupt. */
-	return __request_percpu_irq(TIMER_OOB_IPI,
-			timer_ipi_interrupt_handler,
-			IRQF_OOB, "Xenomai timer IPI",
-			&cobalt_machine_cpudata);
-}
-
-static inline void pipeline_free_timer_ipi(void)
-{
-	/* Release the out-of-band timer interrupt. */
-	free_percpu_irq(TIMER_OOB_IPI, &cobalt_machine_cpudata);
-}
-
 static inline void pipeline_send_timer_ipi(const struct cpumask *dest)
 {
 	/*
@@ -108,15 +78,6 @@ static inline void pipeline_free_resched_ipi(void)
 {
 }
 
-static inline int pipeline_request_timer_ipi(void (*handler)(void))
-{
-	return 0;
-}
-
-static inline void pipeline_free_timer_ipi(void)
-{
-}
-
 #endif	/* CONFIG_SMP */
 
 static inline void pipeline_prepare_panic(void)
diff --git a/kernel/cobalt/dovetail/sched.c b/kernel/cobalt/dovetail/sched.c
index 82e29136ca..de7c43b70c 100644
--- a/kernel/cobalt/dovetail/sched.c
+++ b/kernel/cobalt/dovetail/sched.c
@@ -75,3 +75,11 @@ void pipeline_clear_mayday(void) /* May solely affect current. */
 {
 	clear_thread_flag(TIF_MAYDAY);
 }
+
+irqreturn_t pipeline_reschedule_ipi_handler(int irq, void *dev_id)
+{
+
+	/* Will reschedule from irq_exit_pipeline(). */
+
+	return IRQ_HANDLED;
+}
diff --git a/kernel/cobalt/dovetail/tick.c b/kernel/cobalt/dovetail/tick.c
index 502ec27b22..81eaab84a8 100644
--- a/kernel/cobalt/dovetail/tick.c
+++ b/kernel/cobalt/dovetail/tick.c
@@ -79,12 +79,7 @@ static int proxy_set_next_ktime(ktime_t expires,
 	return ret ? -ETIME : 0;
 }
 
-void xn_core_tick(struct clock_event_device *dummy) /* hard irqs off */
-{
-	xnintr_core_clock_handler();
-}
-
-inline bool pipeline_must_force_program_tick(struct xnsched *sched)
+bool pipeline_must_force_program_tick(struct xnsched *sched)
 {
 	return sched->lflags & XNTSTOP;
 }
@@ -126,7 +121,8 @@ static void setup_proxy(struct clock_proxy_device *dev)
 {
 	struct clock_event_device *proxy_dev = &dev->proxy_device;
 
-	dev->handle_oob_event = xn_core_tick;
+	dev->handle_oob_event = (typeof(dev->handle_oob_event))
+		xnintr_core_clock_handler;
 	proxy_dev->features |= CLOCK_EVT_FEAT_KTIME;
 	proxy_dev->set_next_ktime = proxy_set_next_ktime;
 	if (proxy_dev->set_state_oneshot_stopped)
@@ -134,11 +130,21 @@ static void setup_proxy(struct clock_proxy_device *dev)
 	__this_cpu_write(proxy_device, dev);
 }
 
+static irqreturn_t tick_ipi_handler(int irq, void *dev_id)
+{
+	xnintr_core_clock_handler();
+
+	return IRQ_HANDLED;
+}
+
 int pipeline_install_tick_proxy(void)
 {
 	int ret;
 
-	ret = pipeline_request_timer_ipi(xnintr_core_clock_handler);
+	ret = __request_percpu_irq(TIMER_OOB_IPI,
+				tick_ipi_handler,
+				IRQF_OOB, "Xenomai timer IPI",
+				&cobalt_machine_cpudata);
 	if (ret)
 		return ret;
 
@@ -150,7 +156,7 @@ int pipeline_install_tick_proxy(void)
 	return 0;
 
 fail_proxy:
-	pipeline_free_timer_ipi();
+	free_percpu_irq(TIMER_OOB_IPI, &cobalt_machine_cpudata);
 
 	return ret;
 }
@@ -160,5 +166,5 @@ void pipeline_uninstall_tick_proxy(void)
 	/* Uninstall the proxy tick device. */
 	tick_uninstall_proxy(&xnsched_realtime_cpus);
 
-	pipeline_free_timer_ipi();
+	free_percpu_irq(TIMER_OOB_IPI, &cobalt_machine_cpudata);
 }
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 21/25] cobalt/clock: dovetail: implement pipeline_read_cycle_counter()
  2021-05-20 21:44 [PATCH 00/25] Dovetail integration, next round Jan Kiszka
                   ` (19 preceding siblings ...)
  2021-05-20 21:44 ` [PATCH 20/25] cobalt/tick: dovetail: flatten the call stack to pipeline services Jan Kiszka
@ 2021-05-20 21:44 ` Jan Kiszka
  2021-05-20 21:44 ` [PATCH 22/25] lib/cobalt: ticks: drop cobalt_read_hrclock() Jan Kiszka
                   ` (3 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Jan Kiszka @ 2021-05-20 21:44 UTC (permalink / raw)
  To: xenomai

From: Hongzhan Chen <hongzhan.chen@intel.com>

Signed-off-by: Hongzhan Chen <hongzhan.chen@intel.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 include/cobalt/kernel/dovetail/pipeline/clock.h | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/include/cobalt/kernel/dovetail/pipeline/clock.h b/include/cobalt/kernel/dovetail/pipeline/clock.h
index 82f02d4d77..6761ed70db 100644
--- a/include/cobalt/kernel/dovetail/pipeline/clock.h
+++ b/include/cobalt/kernel/dovetail/pipeline/clock.h
@@ -14,9 +14,7 @@ struct timespec64;
 static inline u64 pipeline_read_cycle_counter(void)
 {
 	/* Read the raw cycle counter of the core clock. */
-	TODO();
-
-	return 0;
+	return  ktime_get_raw_fast_ns();
 }
 
 void pipeline_set_timer_shot(unsigned long cycles);
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 22/25] lib/cobalt: ticks: drop cobalt_read_hrclock()
  2021-05-20 21:44 [PATCH 00/25] Dovetail integration, next round Jan Kiszka
                   ` (20 preceding siblings ...)
  2021-05-20 21:44 ` [PATCH 21/25] cobalt/clock: dovetail: implement pipeline_read_cycle_counter() Jan Kiszka
@ 2021-05-20 21:44 ` Jan Kiszka
  2021-05-20 21:44 ` [PATCH 23/25] lib/cobalt: dovetail: allow representing time as count of nanoseconds Jan Kiszka
                   ` (2 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Jan Kiszka @ 2021-05-20 21:44 UTC (permalink / raw)
  To: xenomai

From: Philippe Gerum <rpm@xenomai.org>

As we move away from the representation of time based on hardware
clock ticks, keeping cobalt_read_hrclock() makes no sense anymore.

This was an internal, undocumented service returning the hardware TSC
value for the platform. The log of commit #d584a57 which introduced it
clearly stated that applications should stick with the common
representation used by clock_gettime(), i.e. nanosecs.

Signed-off-by: Philippe Gerum <rpm@xenomai.org>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 include/cobalt/ticks.h | 2 --
 lib/cobalt/ticks.c     | 5 -----
 2 files changed, 7 deletions(-)

diff --git a/include/cobalt/ticks.h b/include/cobalt/ticks.h
index d9abd390af..2d0132db78 100644
--- a/include/cobalt/ticks.h
+++ b/include/cobalt/ticks.h
@@ -24,8 +24,6 @@
 extern "C" {
 #endif
 
-xnticks_t cobalt_read_hrclock(void);
-
 xnsticks_t cobalt_ticks_to_ns(xnsticks_t ticks);
 
 xnsticks_t cobalt_ticks_to_ns_rounded(xnsticks_t ticks);
diff --git a/lib/cobalt/ticks.c b/lib/cobalt/ticks.c
index 0e5682d832..89d7f51e38 100644
--- a/lib/cobalt/ticks.c
+++ b/lib/cobalt/ticks.c
@@ -99,11 +99,6 @@ unsigned long long cobalt_divrem_billion(unsigned long long value,
 }
 #endif /* !XNARCH_HAVE_NODIV_LLIMD */
 
-xnticks_t cobalt_read_hrclock(void)
-{
-	return cobalt_read_tsc();
-}
-
 void cobalt_ticks_init(unsigned long long freq)
 {
 	clockfreq = freq;
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 23/25] lib/cobalt: dovetail: allow representing time as count of nanoseconds
  2021-05-20 21:44 [PATCH 00/25] Dovetail integration, next round Jan Kiszka
                   ` (21 preceding siblings ...)
  2021-05-20 21:44 ` [PATCH 22/25] lib/cobalt: ticks: drop cobalt_read_hrclock() Jan Kiszka
@ 2021-05-20 21:44 ` Jan Kiszka
  2021-05-20 21:44 ` [PATCH 24/25] lib/cobalt: add default wrapper to clock_settime() Jan Kiszka
  2021-05-20 21:44 ` [PATCH 25/25] lib/cobalt: dovetail: use clock_gettime() vcall for reading timestamps Jan Kiszka
  24 siblings, 0 replies; 26+ messages in thread
From: Jan Kiszka @ 2021-05-20 21:44 UTC (permalink / raw)
  To: xenomai

From: Philippe Gerum <rpm@xenomai.org>

When the core runs on top of Dovetail, all time values are represented
as counts of nanoseconds, in which case a Cobalt tick equals a
nanosecond.

Introduce inline wrappers for tick-to/from-ns conversion which are
nops in the latter case. Cobalt passes us a null clock frequency at
binding time (__cobalt_tsc_clockfreq) when conversion is not needed;
otherwise, the frequency is used in scaled maths for converting
timestamps between their hardware tick and nanosec representation.

Signed-off-by: Philippe Gerum <rpm@xenomai.org>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 include/cobalt/ticks.h | 50 +++++++++++++++++++++++++++++++++++++++---
 lib/cobalt/ticks.c     | 42 +++++++++++++++++++----------------
 2 files changed, 70 insertions(+), 22 deletions(-)

diff --git a/include/cobalt/ticks.h b/include/cobalt/ticks.h
index 2d0132db78..e59d86d499 100644
--- a/include/cobalt/ticks.h
+++ b/include/cobalt/ticks.h
@@ -18,17 +18,61 @@
 #ifndef _COBALT_TICKS_H
 #define _COBALT_TICKS_H
 
+#include <stdbool.h>
 #include <cobalt/uapi/kernel/types.h>
 
+/*
+ * Depending on the underlying pipeline support, we may represent time
+ * stamps as count of nanoseconds (Dovetail), or as values of the
+ * hardware tick counter (aka TSC) available with the platform
+ * (I-pipe). In the latter - legacy - case, we need to convert from
+ * TSC values to nanoseconds and conversely via scaled maths. This
+ * indirection will go away once support for the I-pipe is removed.
+ */
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-xnsticks_t cobalt_ticks_to_ns(xnsticks_t ticks);
+extern unsigned long long __cobalt_tsc_clockfreq;
+
+static inline bool cobalt_use_legacy_tsc(void)
+{
+	return !!__cobalt_tsc_clockfreq;
+}
+
+xnsticks_t __cobalt_tsc_to_ns(xnsticks_t ticks);
+
+xnsticks_t __cobalt_tsc_to_ns_rounded(xnsticks_t ticks);
+
+xnsticks_t __cobalt_ns_to_tsc(xnsticks_t ns);
 
-xnsticks_t cobalt_ticks_to_ns_rounded(xnsticks_t ticks);
+static inline
+xnsticks_t cobalt_ns_to_ticks(xnsticks_t ns)
+{
+	if (cobalt_use_legacy_tsc())
+		return __cobalt_ns_to_tsc(ns);
 
-xnsticks_t cobalt_ns_to_ticks(xnsticks_t ns);
+	return ns;
+}
+
+static inline
+xnsticks_t cobalt_ticks_to_ns(xnsticks_t ticks)
+{
+	if (cobalt_use_legacy_tsc())
+		return __cobalt_tsc_to_ns(ticks);
+
+	return ticks;
+}
+
+static inline
+xnsticks_t cobalt_ticks_to_ns_rounded(xnsticks_t ticks)
+{
+	if (cobalt_use_legacy_tsc())
+		return __cobalt_tsc_to_ns_rounded(ticks);
+
+	return ticks;
+}
 
 unsigned long long cobalt_divrem_billion(unsigned long long value,
 					 unsigned long *rem);
diff --git a/lib/cobalt/ticks.c b/lib/cobalt/ticks.c
index 89d7f51e38..8313258117 100644
--- a/lib/cobalt/ticks.c
+++ b/lib/cobalt/ticks.c
@@ -20,7 +20,7 @@
 #include <asm/xenomai/tsc.h>
 #include "internal.h"
 
-static unsigned long long clockfreq;
+unsigned long long __cobalt_tsc_clockfreq;
 
 #ifdef XNARCH_HAVE_LLMULSHFT
 
@@ -31,11 +31,6 @@ static unsigned int tsc_scale, tsc_shift;
 static struct xnarch_u32frac tsc_frac;
 static struct xnarch_u32frac bln_frac;
 
-xnsticks_t cobalt_ns_to_ticks(xnsticks_t ns)
-{
-	return xnarch_nodiv_llimd(ns, tsc_frac.frac, tsc_frac.integ);
-}
-
 unsigned long long cobalt_divrem_billion(unsigned long long value,
 					 unsigned long *rem)
 {
@@ -52,21 +47,26 @@ unsigned long long cobalt_divrem_billion(unsigned long long value,
 	return q;
 }
 
+xnsticks_t __cobalt_ns_to_tsc(xnsticks_t ns)
+{
+	return xnarch_nodiv_llimd(ns, tsc_frac.frac, tsc_frac.integ);
+}
+
 #else /* !XNARCH_HAVE_NODIV_LLIMD */
 
-xnsticks_t cobalt_ns_to_ticks(xnsticks_t ns)
+xnsticks_t __cobalt_ns_to_tsc(xnsticks_t ns)
 {
 	return xnarch_llimd(ns, 1 << tsc_shift, tsc_scale);
 }
 
 #endif /* !XNARCH_HAVE_NODIV_LLIMD */
 
-xnsticks_t cobalt_ticks_to_ns(xnsticks_t ticks)
+xnsticks_t __cobalt_tsc_to_ns(xnsticks_t ticks)
 {
 	return xnarch_llmulshft(ticks, tsc_scale, tsc_shift);
 }
 
-xnsticks_t cobalt_ticks_to_ns_rounded(xnsticks_t ticks)
+xnsticks_t __cobalt_tsc_to_ns_rounded(xnsticks_t ticks)
 {
 	unsigned int shift = tsc_shift - 1;
 	return (xnarch_llmulshft(ticks, tsc_scale, shift) + 1) / 2;
@@ -74,19 +74,19 @@ xnsticks_t cobalt_ticks_to_ns_rounded(xnsticks_t ticks)
 
 #else  /* !XNARCH_HAVE_LLMULSHFT */
 
-xnsticks_t cobalt_ticks_to_ns(xnsticks_t ticks)
+xnsticks_t __cobalt_tsc_to_ns(xnsticks_t ticks)
 {
-	return xnarch_llimd(ticks, 1000000000, clockfreq);
+	return xnarch_llimd(ticks, 1000000000, __cobalt_tsc_clockfreq);
 }
 
-xnsticks_t cobalt_ticks_to_ns_rounded(xnsticks_t ticks)
+xnsticks_t __cobalt_tsc_to_ns_rounded(xnsticks_t ticks)
 {
-	return (xnarch_llimd(ticks, 1000000000, clockfreq/2) + 1) / 2;
+	return (xnarch_llimd(ticks, 1000000000, __cobalt_tsc_clockfreq/2) + 1) / 2;
 }
 
-xnsticks_t cobalt_ns_to_ticks(xnsticks_t ns)
+xnsticks_t __cobalt_ns_to_tsc(xnsticks_t ns)
 {
-	return xnarch_llimd(ns, clockfreq, 1000000000);
+	return xnarch_llimd(ns, __cobalt_tsc_clockfreq, 1000000000);
 }
 #endif /* !XNARCH_HAVE_LLMULSHFT */
 
@@ -101,12 +101,16 @@ unsigned long long cobalt_divrem_billion(unsigned long long value,
 
 void cobalt_ticks_init(unsigned long long freq)
 {
-	clockfreq = freq;
+	__cobalt_tsc_clockfreq = freq;
 #ifdef XNARCH_HAVE_LLMULSHFT
-	xnarch_init_llmulshft(1000000000, freq, &tsc_scale, &tsc_shift);
+	if (freq) {
+		xnarch_init_llmulshft(1000000000, freq, &tsc_scale, &tsc_shift);
 #ifdef XNARCH_HAVE_NODIV_LLIMD
-	xnarch_init_u32frac(&tsc_frac, 1 << tsc_shift, tsc_scale);
-	xnarch_init_u32frac(&bln_frac, 1, 1000000000);
+		xnarch_init_u32frac(&tsc_frac, 1 << tsc_shift, tsc_scale);
+#endif
+	}
 #endif
+#ifdef XNARCH_HAVE_NODIV_LLIMD
+	xnarch_init_u32frac(&bln_frac, 1, 1000000000);
 #endif
 }
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 24/25] lib/cobalt: add default wrapper to clock_settime()
  2021-05-20 21:44 [PATCH 00/25] Dovetail integration, next round Jan Kiszka
                   ` (22 preceding siblings ...)
  2021-05-20 21:44 ` [PATCH 23/25] lib/cobalt: dovetail: allow representing time as count of nanoseconds Jan Kiszka
@ 2021-05-20 21:44 ` Jan Kiszka
  2021-05-20 21:44 ` [PATCH 25/25] lib/cobalt: dovetail: use clock_gettime() vcall for reading timestamps Jan Kiszka
  24 siblings, 0 replies; 26+ messages in thread
From: Jan Kiszka @ 2021-05-20 21:44 UTC (permalink / raw)
  To: xenomai

From: Philippe Gerum <rpm@xenomai.org>

Signed-off-by: Philippe Gerum <rpm@xenomai.org>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 lib/cobalt/wrappers.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/lib/cobalt/wrappers.c b/lib/cobalt/wrappers.c
index 860b260201..18c237734f 100644
--- a/lib/cobalt/wrappers.c
+++ b/lib/cobalt/wrappers.c
@@ -524,6 +524,12 @@ int __real_clock_gettime(clockid_t clk_id, struct timespec *tp)
 	return clock_gettime(clk_id, tp);
 }
 
+__weak
+int __real_clock_settime(clockid_t clk_id, const struct timespec *tp)
+{
+	return clock_settime(clk_id, tp);
+}
+
 __weak
 int __real_sigwait(const sigset_t *set, int *sig)
 {
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 25/25] lib/cobalt: dovetail: use clock_gettime() vcall for reading timestamps
  2021-05-20 21:44 [PATCH 00/25] Dovetail integration, next round Jan Kiszka
                   ` (23 preceding siblings ...)
  2021-05-20 21:44 ` [PATCH 24/25] lib/cobalt: add default wrapper to clock_settime() Jan Kiszka
@ 2021-05-20 21:44 ` Jan Kiszka
  24 siblings, 0 replies; 26+ messages in thread
From: Jan Kiszka @ 2021-05-20 21:44 UTC (permalink / raw)
  To: xenomai

From: Philippe Gerum <rpm@xenomai.org>

Dovetail enables out-of-band access to the vDSO-based clock_gettime()
vcall from applications. If present, select this method instead of
relying on the hardware tick counter for CLOCK_MONOTONIC,
CLOCK_MONOTONIC_RAW, CLOCK_REALTIME and CLOCK_HOST_REALTIME.

At binding time, receiving a null hardware clock frequency from the
core means that we should obtain timestamps directly from the
vDSO-based clock_gettime() vcall (see cobalt_use_legacy_tsc()).

In this mode, Cobalt shares the in-band kernel's idea of time for all
common clocks such as CLOCK_MONOTONIC* and CLOCK_REALTIME. As a
result, CLOCK_HOST_REALTIME refers to the common CLOCK_REALTIME clock.
Furthermore, libcobalt's clock_settime(CLOCK_REALTIME) is delegated to
the underlying *libc, which means the caller may switch to secondary
mode.

Signed-off-by: Philippe Gerum <rpm@xenomai.org>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 lib/cobalt/Makefile.am                        |   1 +
 .../arch/arm/include/asm/xenomai/time.h       |  16 +
 .../arch/arm64/include/asm/xenomai/time.h     |  16 +
 .../arch/powerpc/include/asm/xenomai/time.h   |  16 +
 .../arch/x86/include/asm/xenomai/time.h       |  16 +
 lib/cobalt/clock.c                            | 107 ++++---
 lib/cobalt/internal.h                         |   6 +
 lib/cobalt/parse_vdso.c                       | 281 ++++++++++++++++++
 lib/cobalt/ticks.c                            |  22 +-
 9 files changed, 445 insertions(+), 36 deletions(-)
 create mode 100644 lib/cobalt/arch/arm/include/asm/xenomai/time.h
 create mode 100644 lib/cobalt/arch/arm64/include/asm/xenomai/time.h
 create mode 100644 lib/cobalt/arch/powerpc/include/asm/xenomai/time.h
 create mode 100644 lib/cobalt/arch/x86/include/asm/xenomai/time.h
 create mode 100644 lib/cobalt/parse_vdso.c

diff --git a/lib/cobalt/Makefile.am b/lib/cobalt/Makefile.am
index ae408b863a..b3003cd957 100644
--- a/lib/cobalt/Makefile.am
+++ b/lib/cobalt/Makefile.am
@@ -22,6 +22,7 @@ libcobalt_la_SOURCES =		\
 	internal.c		\
 	mq.c			\
 	mutex.c			\
+	parse_vdso.c		\
 	printf.c		\
 	rtdm.c			\
 	sched.c			\
diff --git a/lib/cobalt/arch/arm/include/asm/xenomai/time.h b/lib/cobalt/arch/arm/include/asm/xenomai/time.h
new file mode 100644
index 0000000000..34df7e9dff
--- /dev/null
+++ b/lib/cobalt/arch/arm/include/asm/xenomai/time.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2021 Philippe Gerum <rpm@xenomai.org>.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _LIB_COBALT_ARM_TIME_H
+#define _LIB_COBALT_ARM_TIME_H
+
+#define COBALT_VDSO_VERSION	"LINUX_2.6"
+#define COBALT_VDSO_GETTIME	"__vdso_clock_gettime"
+
+#endif /* !_LIB_COBALT_ARM_TIME_H */
diff --git a/lib/cobalt/arch/arm64/include/asm/xenomai/time.h b/lib/cobalt/arch/arm64/include/asm/xenomai/time.h
new file mode 100644
index 0000000000..d0dad6d888
--- /dev/null
+++ b/lib/cobalt/arch/arm64/include/asm/xenomai/time.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2021 Philippe Gerum <rpm@xenomai.org>.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _LIB_COBALT_ARM64_TIME_H
+#define _LIB_COBALT_ARM64_TIME_H
+
+#define COBALT_VDSO_VERSION	"LINUX_2.6.39"
+#define COBALT_VDSO_GETTIME	"__kernel_clock_gettime"
+
+#endif /* !_LIB_COBALT_ARM64_TIME_H */
diff --git a/lib/cobalt/arch/powerpc/include/asm/xenomai/time.h b/lib/cobalt/arch/powerpc/include/asm/xenomai/time.h
new file mode 100644
index 0000000000..92ba44b5a1
--- /dev/null
+++ b/lib/cobalt/arch/powerpc/include/asm/xenomai/time.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2021 Philippe Gerum <rpm@xenomai.org>.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _LIB_COBALT_POWERPC_TIME_H
+#define _LIB_COBALT_POWERPC_TIME_H
+
+#define COBALT_VDSO_VERSION	"LINUX_2.6.15"
+#define COBALT_VDSO_GETTIME	"__kernel_clock_gettime"
+
+#endif /* !_LIB_COBALT_POWERPC_TIME_H */
diff --git a/lib/cobalt/arch/x86/include/asm/xenomai/time.h b/lib/cobalt/arch/x86/include/asm/xenomai/time.h
new file mode 100644
index 0000000000..693be87361
--- /dev/null
+++ b/lib/cobalt/arch/x86/include/asm/xenomai/time.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2021 Philippe Gerum <rpm@xenomai.org>.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _LIB_COBALT_X86_TIME_H
+#define _LIB_COBALT_X86_TIME_H
+
+#define COBALT_VDSO_VERSION	"LINUX_2.6"
+#define COBALT_VDSO_GETTIME	"__vdso_clock_gettime"
+
+#endif /* !_LIB_COBALT_X86_TIME_H */
diff --git a/lib/cobalt/clock.c b/lib/cobalt/clock.c
index 11fd1aa29c..a0673d1fc9 100644
--- a/lib/cobalt/clock.c
+++ b/lib/cobalt/clock.c
@@ -149,6 +149,65 @@ static int __do_clock_host_realtime(struct timespec *ts)
 	return 0;
 }
 
+static int gettime_via_tsc(clockid_t clock_id, struct timespec *tp)
+{
+	unsigned long rem;
+	xnticks_t ns;
+	int ret;
+
+	switch (clock_id) {
+	case CLOCK_HOST_REALTIME:
+		ret = __do_clock_host_realtime(tp);
+		break;
+	case CLOCK_MONOTONIC:
+	case CLOCK_MONOTONIC_RAW:
+		ns = cobalt_ticks_to_ns(cobalt_read_tsc());
+		tp->tv_sec = cobalt_divrem_billion(ns, &rem);
+		tp->tv_nsec = rem;
+		return 0;
+	case CLOCK_REALTIME:
+		ns = cobalt_ticks_to_ns(cobalt_read_tsc());
+		ns += cobalt_vdso->wallclock_offset;
+		tp->tv_sec = cobalt_divrem_billion(ns, &rem);
+		tp->tv_nsec = rem;
+		return 0;
+	default:
+		ret = -XENOMAI_SYSCALL2(sc_cobalt_clock_gettime, clock_id, tp);
+	}
+
+	if (ret) {
+		errno = ret;
+		return -1;
+	}
+
+	return 0;
+}
+
+static int gettime_via_vdso(clockid_t clock_id, struct timespec *tp)
+{
+	int ret;
+
+	switch (clock_id) {
+	case CLOCK_REALTIME:
+	case CLOCK_HOST_REALTIME:
+		ret = __cobalt_vdso_gettime(CLOCK_REALTIME, tp);
+		break;
+	case CLOCK_MONOTONIC:
+	case CLOCK_MONOTONIC_RAW:
+		ret = __cobalt_vdso_gettime(clock_id, tp);
+		break;
+	default:
+		ret = -XENOMAI_SYSCALL2(sc_cobalt_clock_gettime, clock_id, tp);
+	}
+
+	if (ret) {
+		errno = ret;
+		return -1;
+	}
+
+	return 0;
+}
+
 /**
  * Read the specified clock.
  *
@@ -180,63 +239,43 @@ static int __do_clock_host_realtime(struct timespec *ts)
  */
 COBALT_IMPL(int, clock_gettime, (clockid_t clock_id, struct timespec *tp))
 {
-	unsigned long rem;
-	xnticks_t ns;
-	int ret;
+	if (cobalt_use_legacy_tsc())
+		return gettime_via_tsc(clock_id, tp);
 
-	switch (clock_id) {
-	case CLOCK_HOST_REALTIME:
-		ret = __do_clock_host_realtime(tp);
-		break;
-	case CLOCK_MONOTONIC:
-	case CLOCK_MONOTONIC_RAW:
-		ns = cobalt_ticks_to_ns(cobalt_read_tsc());
-		tp->tv_sec = cobalt_divrem_billion(ns, &rem);
-		tp->tv_nsec = rem;
-		return 0;
-	case CLOCK_REALTIME:
-		ns = cobalt_ticks_to_ns(cobalt_read_tsc());
-		ns += cobalt_vdso->wallclock_offset;
-		tp->tv_sec = cobalt_divrem_billion(ns, &rem);
-		tp->tv_nsec = rem;
-		return 0;
-	default:
-		ret = -XENOMAI_SYSCALL2(sc_cobalt_clock_gettime, clock_id, tp);
-	}
-
-	if (ret) {
-		errno = ret;
-		return -1;
-	}
-
-	return 0;
+	return gettime_via_vdso(clock_id, tp);
 }
 
 /**
  * Set the specified clock.
  *
- * This allow setting the CLOCK_REALTIME clock.
+ * Set the CLOCK_REALTIME or Cobalt-specific clocks.
  *
- * @param clock_id the id of the clock to be set, only CLOCK_REALTIME is
- * supported.
+ * @param clock_id the id of the clock to be set. CLOCK_REALTIME,
+ * and Cobalt-specific clocks are supported.
  *
  * @param tp the address of a struct timespec specifying the new date.
  *
  * @retval 0 on success;
  * @retval -1 with @a errno set if:
- * - EINVAL, @a clock_id is not CLOCK_REALTIME;
+ * - EINVAL, @a clock_id is undefined;
  * - EINVAL, the date specified by @a tp is invalid.
  *
  * @see
  * <a href="http://www.opengroup.org/onlinepubs/000095399/functions/clock_settime.html">
  * Specification.</a>
  *
- * @apitags{unrestricted}
+ * @note Setting CLOCK_REALTIME may cause the caller to switch to
+ * secondary mode.
+ *
+ * @apitags{unrestricted, switch-secondary}
  */
 COBALT_IMPL(int, clock_settime, (clockid_t clock_id, const struct timespec *tp))
 {
 	int ret;
 
+	if (clock_id == CLOCK_REALTIME && !cobalt_use_legacy_tsc())
+		return __STD(clock_settime(CLOCK_REALTIME, tp));
+
 	ret = -XENOMAI_SYSCALL2(sc_cobalt_clock_settime, clock_id, tp);
 	if (ret) {
 		errno = ret;
diff --git a/lib/cobalt/internal.h b/lib/cobalt/internal.h
index 4d81b70c2e..acb3989f1b 100644
--- a/lib/cobalt/internal.h
+++ b/lib/cobalt/internal.h
@@ -20,6 +20,7 @@
 
 #include <limits.h>
 #include <stdbool.h>
+#include <time.h>
 #include <boilerplate/ancillaries.h>
 #include <cobalt/sys/cobalt.h>
 #include "current.h"
@@ -87,6 +88,8 @@ int cobalt_xlate_schedparam(int policy,
 			    struct sched_param *param);
 int cobalt_init(void);
 
+void *cobalt_lookup_vdso(const char *version, const char *name);
+
 extern struct sigaction __cobalt_orig_sigdebug;
 
 extern int __cobalt_std_fifo_minpri,
@@ -95,6 +98,9 @@ extern int __cobalt_std_fifo_minpri,
 extern int __cobalt_std_rr_minpri,
 	   __cobalt_std_rr_maxpri;
 
+extern int (*__cobalt_vdso_gettime)(clockid_t clk_id,
+				    struct timespec *tp);
+
 extern unsigned int cobalt_features;
 
 struct cobalt_featinfo;
diff --git a/lib/cobalt/parse_vdso.c b/lib/cobalt/parse_vdso.c
new file mode 100644
index 0000000000..339e4d5645
--- /dev/null
+++ b/lib/cobalt/parse_vdso.c
@@ -0,0 +1,281 @@
+/*
+ * parse_vdso.c: Linux reference vDSO parser
+ * Written by Andrew Lutomirski, 2011-2014.
+ *
+ * This code is meant to be linked in to various programs that run on Linux.
+ * As such, it is available with as few restrictions as possible.  This file
+ * is licensed under the Creative Commons Zero License, version 1.0,
+ * available at http://creativecommons.org/publicdomain/zero/1.0/legalcode
+ *
+ * The vDSO is a regular ELF DSO that the kernel maps into user space when
+ * it starts a program.  It works equally well in statically and dynamically
+ * linked binaries.
+ *
+ * This code is tested on x86.  In principle it should work on any
+ * architecture that has a vDSO.
+ */
+
+#include <sys/types.h>
+#include <sys/auxv.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include <limits.h>
+#include <pthread.h>
+#include <error.h>
+#include <errno.h>
+#include <elf.h>
+#include "internal.h"
+
+/*
+ * To use this vDSO parser, first call one of the vdso_init_* functions.
+ * If you've already parsed auxv, then pass the value of AT_SYSINFO_EHDR
+ * to vdso_init_from_sysinfo_ehdr.  Otherwise pass auxv to vdso_init_from_auxv.
+ * Then call lookup_vdso for each symbol you want.  For example, to look up
+ * gettimeofday on x86_64, use:
+ *
+ *     <some pointer> = lookup_vdso("LINUX_2.6", "gettimeofday");
+ * or
+ *     <some pointer> = lookup_vdso("LINUX_2.6", "__vdso_gettimeofday");
+ *
+ * lookup_vdso will return 0 if the symbol doesn't exist or if the init function
+ * failed or was not called.  lookup_vdso is a little slow, so its return value
+ * should be cached.
+ *
+ * lookup_vdso is threadsafe; the init functions are not.
+ */
+
+
+/* And here's the code. */
+#ifndef ELF_BITS
+# if ULONG_MAX > 0xffffffffUL
+#  define ELF_BITS 64
+# else
+#  define ELF_BITS 32
+# endif
+#endif
+
+#define ELF_BITS_XFORM2(bits, x) Elf##bits##_##x
+#define ELF_BITS_XFORM(bits, x) ELF_BITS_XFORM2(bits, x)
+#define ELF(x) ELF_BITS_XFORM(ELF_BITS, x)
+
+static struct vdso_info
+{
+	bool valid;
+
+	/* Load information */
+	uintptr_t load_addr;
+	uintptr_t load_offset;  /* load_addr - recorded vaddr */
+
+	/* Symbol table */
+	ELF(Sym) *symtab;
+	const char *symstrings;
+	ELF(Word) *bucket, *chain;
+	ELF(Word) nbucket, nchain;
+
+	/* Version table */
+	ELF(Versym) *versym;
+	ELF(Verdef) *verdef;
+} vdso_info;
+
+/* Straight from the ELF specification. */
+static unsigned long elf_hash(const char *name)
+{
+	unsigned long h = 0, g;
+	while (*name)
+	{
+		h = (h << 4) + *name++;
+		if ((g = h & 0xf0000000))
+			h ^= g >> 24;
+		h &= ~g;
+	}
+	return h;
+}
+
+static void vdso_init_from_sysinfo_ehdr(uintptr_t base)
+{
+	size_t i;
+	bool found_vaddr = false;
+
+	vdso_info.valid = false;
+
+	vdso_info.load_addr = base;
+
+	ELF(Ehdr) *hdr = (ELF(Ehdr)*)base;
+	if (hdr->e_ident[EI_CLASS] !=
+	    (ELF_BITS == 32 ? ELFCLASS32 : ELFCLASS64)) {
+		return;  /* Wrong ELF class -- check ELF_BITS */
+	}
+
+	ELF(Phdr) *pt = (ELF(Phdr)*)(vdso_info.load_addr + hdr->e_phoff);
+	ELF(Dyn) *dyn = 0;
+
+	/*
+	 * We need two things from the segment table: the load offset
+	 * and the dynamic table.
+	 */
+	for (i = 0; i < hdr->e_phnum; i++)
+	{
+		if (pt[i].p_type == PT_LOAD && !found_vaddr) {
+			found_vaddr = true;
+			vdso_info.load_offset =	base
+				+ (uintptr_t)pt[i].p_offset
+				- (uintptr_t)pt[i].p_vaddr;
+		} else if (pt[i].p_type == PT_DYNAMIC) {
+			dyn = (ELF(Dyn)*)(base + pt[i].p_offset);
+		}
+	}
+
+	if (!found_vaddr || !dyn)
+		return;  /* Failed */
+
+	/*
+	 * Fish out the useful bits of the dynamic table.
+	 */
+	ELF(Word) *hash = 0;
+	vdso_info.symstrings = 0;
+	vdso_info.symtab = 0;
+	vdso_info.versym = 0;
+	vdso_info.verdef = 0;
+	for (i = 0; dyn[i].d_tag != DT_NULL; i++) {
+		switch (dyn[i].d_tag) {
+		case DT_STRTAB:
+			vdso_info.symstrings = (const char *)
+				((uintptr_t)dyn[i].d_un.d_ptr
+				 + vdso_info.load_offset);
+			break;
+		case DT_SYMTAB:
+			vdso_info.symtab = (ELF(Sym) *)
+				((uintptr_t)dyn[i].d_un.d_ptr
+				 + vdso_info.load_offset);
+			break;
+		case DT_HASH:
+			hash = (ELF(Word) *)
+				((uintptr_t)dyn[i].d_un.d_ptr
+				 + vdso_info.load_offset);
+			break;
+		case DT_VERSYM:
+			vdso_info.versym = (ELF(Versym) *)
+				((uintptr_t)dyn[i].d_un.d_ptr
+				 + vdso_info.load_offset);
+			break;
+		case DT_VERDEF:
+			vdso_info.verdef = (ELF(Verdef) *)
+				((uintptr_t)dyn[i].d_un.d_ptr
+				 + vdso_info.load_offset);
+			break;
+		}
+	}
+	if (!vdso_info.symstrings || !vdso_info.symtab || !hash)
+		return;  /* Failed */
+
+	if (!vdso_info.verdef)
+		vdso_info.versym = 0;
+
+	/* Parse the hash table header. */
+	vdso_info.nbucket = hash[0];
+	vdso_info.nchain = hash[1];
+	vdso_info.bucket = &hash[2];
+	vdso_info.chain = &hash[vdso_info.nbucket + 2];
+
+	/* That's all we need. */
+	vdso_info.valid = true;
+}
+
+static bool vdso_match_version(ELF(Versym) ver,
+			       const char *name, ELF(Word) hash)
+{
+	/*
+	 * This is a helper function to check if the version indexed by
+	 * ver matches name (which hashes to hash).
+	 *
+	 * The version definition table is a mess, and I don't know how
+	 * to do this in better than linear time without allocating memory
+	 * to build an index.  I also don't know why the table has
+	 * variable size entries in the first place.
+	 *
+	 * For added fun, I can't find a comprehensible specification of how
+	 * to parse all the weird flags in the table.
+	 *
+	 * So I just parse the whole table every time.
+	 */
+
+	/* First step: find the version definition */
+	ver &= 0x7fff;  /* Apparently bit 15 means "hidden" */
+	ELF(Verdef) *def = vdso_info.verdef;
+	while(true) {
+		if ((def->vd_flags & VER_FLG_BASE) == 0
+		    && (def->vd_ndx & 0x7fff) == ver)
+			break;
+
+		if (def->vd_next == 0)
+			return false;  /* No definition. */
+
+		def = (ELF(Verdef) *)((char *)def + def->vd_next);
+	}
+
+	/* Now figure out whether it matches. */
+	ELF(Verdaux) *aux = (ELF(Verdaux)*)((char *)def + def->vd_aux);
+	return def->vd_hash == hash
+		&& !strcmp(name, vdso_info.symstrings + aux->vda_name);
+}
+
+static void *lookup_vdso(const char *version, const char *name)
+{
+	unsigned long ver_hash;
+
+	if (!vdso_info.valid)
+		return 0;
+
+	ver_hash = elf_hash(version);
+	ELF(Word) chain = vdso_info.bucket[elf_hash(name) % vdso_info.nbucket];
+
+	for (; chain != STN_UNDEF; chain = vdso_info.chain[chain]) {
+		ELF(Sym) *sym = &vdso_info.symtab[chain];
+
+		/* Check for a defined global or weak function w/ right name. */
+		if (ELF64_ST_TYPE(sym->st_info) != STT_FUNC)
+			continue;
+		if (ELF64_ST_BIND(sym->st_info) != STB_GLOBAL &&
+		    ELF64_ST_BIND(sym->st_info) != STB_WEAK)
+			continue;
+		if (sym->st_shndx == SHN_UNDEF)
+			continue;
+		if (strcmp(name, vdso_info.symstrings + sym->st_name))
+			continue;
+
+		/* Check symbol version. */
+		if (vdso_info.versym
+		    && !vdso_match_version(vdso_info.versym[chain],
+					   version, ver_hash))
+			continue;
+
+		return (void *)(vdso_info.load_offset + sym->st_value);
+	}
+
+	return 0;
+}
+
+static void parse_vdso(void)
+{
+	uintptr_t vdso = (uintptr_t)getauxval(AT_SYSINFO_EHDR);
+
+	if (!vdso)
+		error(1, ENOENT, "vDSO signature not found");
+
+	vdso_init_from_sysinfo_ehdr(vdso);
+}
+
+void *cobalt_lookup_vdso(const char *version, const char *name)
+{
+	static pthread_once_t parse_vdso_once = PTHREAD_ONCE_INIT;
+	void *sym;
+
+	pthread_once(&parse_vdso_once, parse_vdso);
+
+	sym = lookup_vdso(version, name);
+	if (!sym)
+		error(1, ENOENT, "%s not found in vDSO", name);
+
+	return sym;
+}
diff --git a/lib/cobalt/ticks.c b/lib/cobalt/ticks.c
index 8313258117..94e0c1b0d3 100644
--- a/lib/cobalt/ticks.c
+++ b/lib/cobalt/ticks.c
@@ -18,10 +18,23 @@
 #include <cobalt/arith.h>
 #include <cobalt/ticks.h>
 #include <asm/xenomai/tsc.h>
+#include <asm/xenomai/time.h>
 #include "internal.h"
 
 unsigned long long __cobalt_tsc_clockfreq;
 
+/*
+ * If we have no fast path via the vDSO for reading timestamps, ask
+ * the Cobalt core.
+ */
+static int gettime_fallback(clockid_t clk_id, struct timespec *tp)
+{
+	return __RT(clock_gettime(clk_id, tp));
+}
+
+int (*__cobalt_vdso_gettime)(clockid_t clk_id,
+			struct timespec *tp) = gettime_fallback;
+
 #ifdef XNARCH_HAVE_LLMULSHFT
 
 static unsigned int tsc_scale, tsc_shift;
@@ -102,14 +115,19 @@ unsigned long long cobalt_divrem_billion(unsigned long long value,
 void cobalt_ticks_init(unsigned long long freq)
 {
 	__cobalt_tsc_clockfreq = freq;
-#ifdef XNARCH_HAVE_LLMULSHFT
 	if (freq) {
+#ifdef XNARCH_HAVE_LLMULSHFT
 		xnarch_init_llmulshft(1000000000, freq, &tsc_scale, &tsc_shift);
 #ifdef XNARCH_HAVE_NODIV_LLIMD
 		xnarch_init_u32frac(&tsc_frac, 1 << tsc_shift, tsc_scale);
 #endif
-	}
 #endif
+	} else {
+		void *vcall = cobalt_lookup_vdso(COBALT_VDSO_VERSION,
+						 COBALT_VDSO_GETTIME);
+		if (vcall)
+			__cobalt_vdso_gettime = vcall;
+	}
 #ifdef XNARCH_HAVE_NODIV_LLIMD
 	xnarch_init_u32frac(&bln_frac, 1, 1000000000);
 #endif
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2021-05-20 21:44 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-20 21:44 [PATCH 00/25] Dovetail integration, next round Jan Kiszka
2021-05-20 21:44 ` [PATCH 01/25] cobalt/kernel: ipipe: rename xnsched_realtime_domain to xnsched_primary_domain Jan Kiszka
2021-05-20 21:44 ` [PATCH 02/25] cobalt/kevents: dovetail: drop call to obsolete force_commit_memory() Jan Kiszka
2021-05-20 21:44 ` [PATCH 03/25] cobalt/intr: dovetail: implement interrupt management, handling Jan Kiszka
2021-05-20 21:44 ` [PATCH 04/25] cobalt/irq: dovetail: implement out-of-band irq management and handling Jan Kiszka
2021-05-20 21:44 ` [PATCH 05/25] cobalt/kevents: dovetail: enable back tracing Jan Kiszka
2021-05-20 21:44 ` [PATCH 06/25] cobalt/x86: ipipe: Remove leftover from x86_32 removal Jan Kiszka
2021-05-20 21:44 ` [PATCH 07/25] cobalt/x86: ipipe: Drop unused strncpy_from_user_nocheck Jan Kiszka
2021-05-20 21:44 ` [PATCH 08/25] cobalt/x86: Move shared headers out of pipeline specific folder Jan Kiszka
2021-05-20 21:44 ` [PATCH 09/25] cobalt/x86: dovetail: add architecture bits Jan Kiszka
2021-05-20 21:44 ` [PATCH 10/25] cobalt/kernel: dovetail: implement sirq services Jan Kiszka
2021-05-20 21:44 ` [PATCH 11/25] cobalt/sched: dovetail: add task control block initializers Jan Kiszka
2021-05-20 21:44 ` [PATCH 12/25] cobalt/clock: dovetail: provide backend code to CLOCK_HOST_REALTIME Jan Kiszka
2021-05-20 21:44 ` [PATCH 13/25] cobalt/init: dovetail: add oob stage enabling, disabling services Jan Kiszka
2021-05-20 21:44 ` [PATCH 14/25] cobalt/timer: Check if nklock is held in timer services Jan Kiszka
2021-05-20 21:44 ` [PATCH 15/25] cobalt/tick: dovetail: install/uninstall proxy tick device Jan Kiszka
2021-05-20 21:44 ` [PATCH 16/25] cobalt/tick: dovetail: implement pipeline_set_timer_shot() Jan Kiszka
2021-05-20 21:44 ` [PATCH 17/25] cobalt/tick: dovetail: implement pipeline_timer_name() Jan Kiszka
2021-05-20 21:44 ` [PATCH 18/25] cobalt/timer: pipeline: abstract handling of ONESHOT_STOPPED mode Jan Kiszka
2021-05-20 21:44 ` [PATCH 19/25] cobalt/timer: dovetail: handle " Jan Kiszka
2021-05-20 21:44 ` [PATCH 20/25] cobalt/tick: dovetail: flatten the call stack to pipeline services Jan Kiszka
2021-05-20 21:44 ` [PATCH 21/25] cobalt/clock: dovetail: implement pipeline_read_cycle_counter() Jan Kiszka
2021-05-20 21:44 ` [PATCH 22/25] lib/cobalt: ticks: drop cobalt_read_hrclock() Jan Kiszka
2021-05-20 21:44 ` [PATCH 23/25] lib/cobalt: dovetail: allow representing time as count of nanoseconds Jan Kiszka
2021-05-20 21:44 ` [PATCH 24/25] lib/cobalt: add default wrapper to clock_settime() Jan Kiszka
2021-05-20 21:44 ` [PATCH 25/25] lib/cobalt: dovetail: use clock_gettime() vcall for reading timestamps Jan Kiszka

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.