# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1169219379 0
# Node ID e9e327c3e81b2d5682307246f81d4cb53d2975f0
# Parent 374688d2db788b1a81c2e544bbaba2e9b6f898c7
[MINIOS] More cleanups for the ia64 port.
Signed-off-by: Dietmar Hahn <dietmar.hahn@xxxxxxxxxxxxxxxxxxx>
---
extras/mini-os/time.c | 225 ----------------------------------------
extras/mini-os/arch/x86/sched.c | 20 ---
extras/mini-os/arch/x86/time.c | 225 ++++++++++++++++++++++++++++++++++++++++
extras/mini-os/include/sched.h | 3
extras/mini-os/lib/math.c | 5
extras/mini-os/lib/xmalloc.c | 6 +
extras/mini-os/sched.c | 26 +++-
7 files changed, 263 insertions(+), 247 deletions(-)
diff -r 374688d2db78 -r e9e327c3e81b extras/mini-os/arch/x86/sched.c
--- a/extras/mini-os/arch/x86/sched.c Fri Jan 19 15:08:15 2007 +0000
+++ b/extras/mini-os/arch/x86/sched.c Fri Jan 19 15:09:39 2007 +0000
@@ -91,10 +91,11 @@ static void stack_push(struct thread *th
*((unsigned long *)thread->sp) = value;
}
-struct thread* create_thread(char *name, void (*function)(void *), void *data)
+/* Architecture specific setup of thread creation */
+struct thread* arch_create_thread(char *name, void (*function)(void *),
+ void *data)
{
struct thread *thread;
- unsigned long flags;
thread = xmalloc(struct thread);
/* Allocate 2 pages for stack, stack will be 2pages aligned */
@@ -110,23 +111,8 @@ struct thread* create_thread(char *name,
stack_push(thread, (unsigned long) function);
stack_push(thread, (unsigned long) data);
thread->ip = (unsigned long) thread_starter;
-
- /* Not runable, not exited, not sleeping */
- thread->flags = 0;
- thread->wakeup_time = 0LL;
- set_runnable(thread);
- local_irq_save(flags);
- if(idle_thread != NULL) {
- list_add_tail(&thread->thread_list, &idle_thread->thread_list);
- } else if(function != idle_thread_fn)
- {
- printk("BUG: Not allowed to create thread before initialising
scheduler.\n");
- BUG();
- }
- local_irq_restore(flags);
return thread;
}
-
void run_idle_thread(void)
{
diff -r 374688d2db78 -r e9e327c3e81b extras/mini-os/arch/x86/time.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/mini-os/arch/x86/time.c Fri Jan 19 15:09:39 2007 +0000
@@ -0,0 +1,225 @@
+/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*-
+ ****************************************************************************
+ * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge
+ * (C) 2002-2003 - Keir Fraser - University of Cambridge
+ * (C) 2005 - Grzegorz Milos - Intel Research Cambridge
+ * (C) 2006 - Robert Kaiser - FH Wiesbaden
+ ****************************************************************************
+ *
+ * File: time.c
+ * Author: Rolf Neugebauer and Keir Fraser
+ * Changes: Grzegorz Milos
+ *
+ * Description: Simple time and timer functions
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include <os.h>
+#include <traps.h>
+#include <types.h>
+#include <hypervisor.h>
+#include <events.h>
+#include <time.h>
+#include <lib.h>
+
+/************************************************************************
+ * Time functions
+ *************************************************************************/
+
+/* These are peridically updated in shared_info, and then copied here. */
+struct shadow_time_info {
+ u64 tsc_timestamp; /* TSC at last update of time vals. */
+ u64 system_timestamp; /* Time, in nanosecs, since boot. */
+ u32 tsc_to_nsec_mul;
+ u32 tsc_to_usec_mul;
+ int tsc_shift;
+ u32 version;
+};
+static struct timespec shadow_ts;
+static u32 shadow_ts_version;
+
+static struct shadow_time_info shadow;
+
+
+#ifndef rmb
+#define rmb() __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory")
+#endif
+
+#define HANDLE_USEC_OVERFLOW(_tv) \
+ do { \
+ while ( (_tv)->tv_usec >= 1000000 ) \
+ { \
+ (_tv)->tv_usec -= 1000000; \
+ (_tv)->tv_sec++; \
+ } \
+ } while ( 0 )
+
+static inline int time_values_up_to_date(void)
+{
+ struct vcpu_time_info *src =
&HYPERVISOR_shared_info->vcpu_info[0].time;
+
+ return (shadow.version == src->version);
+}
+
+
+/*
+ * Scale a 64-bit delta by scaling and multiplying by a 32-bit fraction,
+ * yielding a 64-bit result.
+ */
+static inline u64 scale_delta(u64 delta, u32 mul_frac, int shift)
+{
+ u64 product;
+#ifdef __i386__
+ u32 tmp1, tmp2;
+#endif
+
+ if ( shift < 0 )
+ delta >>= -shift;
+ else
+ delta <<= shift;
+
+#ifdef __i386__
+ __asm__ (
+ "mul %5 ; "
+ "mov %4,%%eax ; "
+ "mov %%edx,%4 ; "
+ "mul %5 ; "
+ "add %4,%%eax ; "
+ "xor %5,%5 ; "
+ "adc %5,%%edx ; "
+ : "=A" (product), "=r" (tmp1), "=r" (tmp2)
+ : "a" ((u32)delta), "1" ((u32)(delta >> 32)), "2" (mul_frac) );
+#else
+ __asm__ (
+ "mul %%rdx ; shrd $32,%%rdx,%%rax"
+ : "=a" (product) : "0" (delta), "d" ((u64)mul_frac) );
+#endif
+
+ return product;
+}
+
+
+static unsigned long get_nsec_offset(void)
+{
+ u64 now, delta;
+ rdtscll(now);
+ delta = now - shadow.tsc_timestamp;
+ return scale_delta(delta, shadow.tsc_to_nsec_mul, shadow.tsc_shift);
+}
+
+
+static void get_time_values_from_xen(void)
+{
+ struct vcpu_time_info *src =
&HYPERVISOR_shared_info->vcpu_info[0].time;
+
+ do {
+ shadow.version = src->version;
+ rmb();
+ shadow.tsc_timestamp = src->tsc_timestamp;
+ shadow.system_timestamp = src->system_time;
+ shadow.tsc_to_nsec_mul = src->tsc_to_system_mul;
+ shadow.tsc_shift = src->tsc_shift;
+ rmb();
+ }
+ while ((src->version & 1) | (shadow.version ^ src->version));
+
+ shadow.tsc_to_usec_mul = shadow.tsc_to_nsec_mul / 1000;
+}
+
+
+
+
+/* monotonic_clock(): returns # of nanoseconds passed since time_init()
+ * Note: This function is required to return accurate
+ * time even in the absence of multiple timer ticks.
+ */
+u64 monotonic_clock(void)
+{
+ u64 time;
+ u32 local_time_version;
+
+ do {
+ local_time_version = shadow.version;
+ rmb();
+ time = shadow.system_timestamp + get_nsec_offset();
+ if (!time_values_up_to_date())
+ get_time_values_from_xen();
+ rmb();
+ } while (local_time_version != shadow.version);
+
+ return time;
+}
+
+static void update_wallclock(void)
+{
+ shared_info_t *s = HYPERVISOR_shared_info;
+
+ do {
+ shadow_ts_version = s->wc_version;
+ rmb();
+ shadow_ts.ts_sec = s->wc_sec;
+ shadow_ts.ts_nsec = s->wc_nsec;
+ rmb();
+ }
+ while ((s->wc_version & 1) | (shadow_ts_version ^ s->wc_version));
+}
+
+
+void gettimeofday(struct timeval *tv)
+{
+ u64 nsec = monotonic_clock();
+ nsec += shadow_ts.ts_nsec;
+
+
+ tv->tv_sec = shadow_ts.ts_sec;
+ tv->tv_sec += NSEC_TO_SEC(nsec);
+ tv->tv_usec = NSEC_TO_USEC(nsec % 1000000000UL);
+}
+
+
+void block_domain(s_time_t until)
+{
+ struct timeval tv;
+ gettimeofday(&tv);
+ if(monotonic_clock() < until)
+ {
+ HYPERVISOR_set_timer_op(until);
+ HYPERVISOR_sched_op(SCHEDOP_block, 0);
+ }
+}
+
+
+/*
+ * Just a dummy
+ */
+static void timer_handler(evtchn_port_t ev, struct pt_regs *regs, void *ign)
+{
+ get_time_values_from_xen();
+ update_wallclock();
+}
+
+
+
+void init_time(void)
+{
+ printk("Initialising timer interface\n");
+ bind_virq(VIRQ_TIMER, &timer_handler, NULL);
+}
diff -r 374688d2db78 -r e9e327c3e81b extras/mini-os/include/sched.h
--- a/extras/mini-os/include/sched.h Fri Jan 19 15:08:15 2007 +0000
+++ b/extras/mini-os/include/sched.h Fri Jan 19 15:09:39 2007 +0000
@@ -31,6 +31,9 @@ void idle_thread_fn(void *unused);
#define switch_threads(prev, next) arch_switch_threads(prev, next)
+ /* Architecture specific setup of thread creation. */
+struct thread* arch_create_thread(char *name, void (*function)(void *),
+ void *data);
void init_sched(void);
void run_idle_thread(void);
diff -r 374688d2db78 -r e9e327c3e81b extras/mini-os/lib/math.c
--- a/extras/mini-os/lib/math.c Fri Jan 19 15:08:15 2007 +0000
+++ b/extras/mini-os/lib/math.c Fri Jan 19 15:09:39 2007 +0000
@@ -56,6 +56,10 @@
*/
#include <types.h>
+
+ /* On ia64 these functions lead to crashes. These are replaced by
+ * assembler functions. */
+#if !defined(__ia64__)
/*
* Depending on the desired operation, we view a `long long' (aka quad_t) in
@@ -380,3 +384,4 @@ __umoddi3(u_quad_t a, u_quad_t b)
return (r);
}
+#endif /* !defined(__ia64__) */
diff -r 374688d2db78 -r e9e327c3e81b extras/mini-os/lib/xmalloc.c
--- a/extras/mini-os/lib/xmalloc.c Fri Jan 19 15:08:15 2007 +0000
+++ b/extras/mini-os/lib/xmalloc.c Fri Jan 19 15:09:39 2007 +0000
@@ -48,6 +48,12 @@ struct xmalloc_hdr
/* Total including this hdr. */
size_t size;
struct list_head freelist;
+#if defined(__ia64__)
+ // Needed for ia64 as long as the align parameter in _xmalloc()
+ // is not supported.
+ uint64_t pad;
+#endif
+
} __cacheline_aligned;
static void maybe_split(struct xmalloc_hdr *hdr, size_t size, size_t block)
diff -r 374688d2db78 -r e9e327c3e81b extras/mini-os/sched.c
--- a/extras/mini-os/sched.c Fri Jan 19 15:08:15 2007 +0000
+++ b/extras/mini-os/sched.c Fri Jan 19 15:09:39 2007 +0000
@@ -155,11 +155,27 @@ void schedule(void)
if(prev != next) switch_threads(prev, next);
}
-
-/* Gets run when a new thread is scheduled the first time ever,
- defined in x86_[32/64].S */
-extern void thread_starter(void);
-
+struct thread* create_thread(char *name, void (*function)(void *), void *data)
+{
+ struct thread *thread;
+ unsigned long flags;
+ /* Call architecture specific setup. */
+ thread = arch_create_thread(name, function, data);
+ /* Not runable, not exited, not sleeping */
+ thread->flags = 0;
+ thread->wakeup_time = 0LL;
+ set_runnable(thread);
+ local_irq_save(flags);
+ if(idle_thread != NULL) {
+ list_add_tail(&thread->thread_list, &idle_thread->thread_list);
+ } else if(function != idle_thread_fn)
+ {
+ printk("BUG: Not allowed to create thread before initialising
scheduler.\n");
+ BUG();
+ }
+ local_irq_restore(flags);
+ return thread;
+}
void exit_thread(void)
{
diff -r 374688d2db78 -r e9e327c3e81b extras/mini-os/time.c
--- a/extras/mini-os/time.c Fri Jan 19 15:08:15 2007 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,225 +0,0 @@
-/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*-
- ****************************************************************************
- * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge
- * (C) 2002-2003 - Keir Fraser - University of Cambridge
- * (C) 2005 - Grzegorz Milos - Intel Research Cambridge
- * (C) 2006 - Robert Kaiser - FH Wiesbaden
- ****************************************************************************
- *
- * File: time.c
- * Author: Rolf Neugebauer and Keir Fraser
- * Changes: Grzegorz Milos
- *
- * Description: Simple time and timer functions
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-
-#include <os.h>
-#include <traps.h>
-#include <types.h>
-#include <hypervisor.h>
-#include <events.h>
-#include <time.h>
-#include <lib.h>
-
-/************************************************************************
- * Time functions
- *************************************************************************/
-
-/* These are peridically updated in shared_info, and then copied here. */
-struct shadow_time_info {
- u64 tsc_timestamp; /* TSC at last update of time vals. */
- u64 system_timestamp; /* Time, in nanosecs, since boot. */
- u32 tsc_to_nsec_mul;
- u32 tsc_to_usec_mul;
- int tsc_shift;
- u32 version;
-};
-static struct timespec shadow_ts;
-static u32 shadow_ts_version;
-
-static struct shadow_time_info shadow;
-
-
-#ifndef rmb
-#define rmb() __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory")
-#endif
-
-#define HANDLE_USEC_OVERFLOW(_tv) \
- do { \
- while ( (_tv)->tv_usec >= 1000000 ) \
- { \
- (_tv)->tv_usec -= 1000000; \
- (_tv)->tv_sec++; \
- } \
- } while ( 0 )
-
-static inline int time_values_up_to_date(void)
-{
- struct vcpu_time_info *src =
&HYPERVISOR_shared_info->vcpu_info[0].time;
-
- return (shadow.version == src->version);
-}
-
-
-/*
- * Scale a 64-bit delta by scaling and multiplying by a 32-bit fraction,
- * yielding a 64-bit result.
- */
-static inline u64 scale_delta(u64 delta, u32 mul_frac, int shift)
-{
- u64 product;
-#ifdef __i386__
- u32 tmp1, tmp2;
-#endif
-
- if ( shift < 0 )
- delta >>= -shift;
- else
- delta <<= shift;
-
-#ifdef __i386__
- __asm__ (
- "mul %5 ; "
- "mov %4,%%eax ; "
- "mov %%edx,%4 ; "
- "mul %5 ; "
- "add %4,%%eax ; "
- "xor %5,%5 ; "
- "adc %5,%%edx ; "
- : "=A" (product), "=r" (tmp1), "=r" (tmp2)
- : "a" ((u32)delta), "1" ((u32)(delta >> 32)), "2" (mul_frac) );
-#else
- __asm__ (
- "mul %%rdx ; shrd $32,%%rdx,%%rax"
- : "=a" (product) : "0" (delta), "d" ((u64)mul_frac) );
-#endif
-
- return product;
-}
-
-
-static unsigned long get_nsec_offset(void)
-{
- u64 now, delta;
- rdtscll(now);
- delta = now - shadow.tsc_timestamp;
- return scale_delta(delta, shadow.tsc_to_nsec_mul, shadow.tsc_shift);
-}
-
-
-static void get_time_values_from_xen(void)
-{
- struct vcpu_time_info *src =
&HYPERVISOR_shared_info->vcpu_info[0].time;
-
- do {
- shadow.version = src->version;
- rmb();
- shadow.tsc_timestamp = src->tsc_timestamp;
- shadow.system_timestamp = src->system_time;
- shadow.tsc_to_nsec_mul = src->tsc_to_system_mul;
- shadow.tsc_shift = src->tsc_shift;
- rmb();
- }
- while ((src->version & 1) | (shadow.version ^ src->version));
-
- shadow.tsc_to_usec_mul = shadow.tsc_to_nsec_mul / 1000;
-}
-
-
-
-
-/* monotonic_clock(): returns # of nanoseconds passed since time_init()
- * Note: This function is required to return accurate
- * time even in the absence of multiple timer ticks.
- */
-u64 monotonic_clock(void)
-{
- u64 time;
- u32 local_time_version;
-
- do {
- local_time_version = shadow.version;
- rmb();
- time = shadow.system_timestamp + get_nsec_offset();
- if (!time_values_up_to_date())
- get_time_values_from_xen();
- rmb();
- } while (local_time_version != shadow.version);
-
- return time;
-}
-
-static void update_wallclock(void)
-{
- shared_info_t *s = HYPERVISOR_shared_info;
-
- do {
- shadow_ts_version = s->wc_version;
- rmb();
- shadow_ts.ts_sec = s->wc_sec;
- shadow_ts.ts_nsec = s->wc_nsec;
- rmb();
- }
- while ((s->wc_version & 1) | (shadow_ts_version ^ s->wc_version));
-}
-
-
-void gettimeofday(struct timeval *tv)
-{
- u64 nsec = monotonic_clock();
- nsec += shadow_ts.ts_nsec;
-
-
- tv->tv_sec = shadow_ts.ts_sec;
- tv->tv_sec += NSEC_TO_SEC(nsec);
- tv->tv_usec = NSEC_TO_USEC(nsec % 1000000000UL);
-}
-
-
-void block_domain(s_time_t until)
-{
- struct timeval tv;
- gettimeofday(&tv);
- if(monotonic_clock() < until)
- {
- HYPERVISOR_set_timer_op(until);
- HYPERVISOR_sched_op(SCHEDOP_block, 0);
- }
-}
-
-
-/*
- * Just a dummy
- */
-static void timer_handler(evtchn_port_t ev, struct pt_regs *regs, void *ign)
-{
- get_time_values_from_xen();
- update_wallclock();
-}
-
-
-
-void init_time(void)
-{
- printk("Initialising timer interface\n");
- bind_virq(VIRQ_TIMER, &timer_handler, NULL);
-}
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|