* [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