[arch] update all the arches to implement get_current_thread()

-For ARM and ARM64, use the cpu local registers
-for X86, X86-64, and ARM-M, use a global variable
This commit is contained in:
Travis Geiselbrecht
2014-05-03 23:58:50 -07:00
parent 94920d35d1
commit a99a962333
10 changed files with 100 additions and 15 deletions

View File

@@ -44,22 +44,25 @@ struct arm_cm_context_switch_frame {
uint32_t lr;
};
/* since we're implicitly uniprocessor, store a pointer to the current thread here */
thread_t *_current_thread;
static void initial_thread_func(void) __NO_RETURN;
static void initial_thread_func(void)
{
int ret;
LTRACEF("thread %p calling %p with arg %p\n", current_thread, current_thread->entry, current_thread->arg);
LTRACEF("thread %p calling %p with arg %p\n", _current_thread, _current_thread->entry, _current_thread->arg);
#if LOCAL_TRACE
dump_thread(current_thread);
dump_thread(_current_thread);
#endif
/* exit the implicit critical section we're within */
exit_critical_section();
ret = current_thread->entry(current_thread->arg);
ret = _current_thread->entry(_current_thread->arg);
LTRACEF("thread %p exiting with %d\n", current_thread, ret);
LTRACEF("thread %p exiting with %d\n", _current_thread, ret);
thread_exit(ret);
}
@@ -90,7 +93,7 @@ static void pendsv(struct arm_cm_exception_frame_long *frame)
ASSERT(critical_section_count == 1);
LTRACEF("preempting thread %p (%s)\n", current_thread, current_thread->name);
LTRACEF("preempting thread %p (%s)\n", _current_thread, _current_thread->name);
/* save the iframe the pendsv fired on and hit the preemption code */
preempt_frame = frame;

View File

@@ -52,7 +52,8 @@ static void initial_thread_func(void)
/* exit the implicit critical section we're within */
exit_critical_section();
ret = current_thread->entry(current_thread->arg);
thread_t *ct = get_current_thread();
ret = ct->entry(ct->arg);
// dprintf("initial_thread_func: thread %p exiting with %d\n", current_thread, ret);

View File

@@ -28,6 +28,7 @@
#include <stdbool.h>
#include <compiler.h>
#include <reg.h>
#include <arch/arm.h>
#if ARM_ISA_ARMV7 || (ARM_ISA_ARMV6 && !__thumb__)
#define USE_GCC_ATOMICS 0
@@ -224,6 +225,36 @@ static inline uint32_t arch_cycle_count(void)
#endif
}
/* defined in kernel/thread.h */
#if !ARM_ISA_ARMV7M
/* use the cpu local thread context pointer to store current_thread */
static inline struct thread *get_current_thread(void)
{
return (struct thread *)arm_read_tpidrprw();
}
static inline void set_current_thread(struct thread *t)
{
arm_write_tpidrprw((uint32_t)t);
}
#else // ARM_ISA_ARM7M
/* use a global pointer to store the current_thread */
extern struct thread *_current_thread;
static inline struct thread *get_current_thread(void)
{
return _current_thread;
}
static inline void set_current_thread(struct thread *t)
{
_current_thread = t;
}
#endif // !ARM_ISA_ARMV7M
#else // pre-armv6 || (armv6 & thumb)
/* for pre-armv6 the bodies of these are too big to inline, call an assembly stub version */

View File

@@ -27,6 +27,7 @@
#include <stdbool.h>
#include <compiler.h>
#include <reg.h>
#include <arch/arm64.h>
#define USE_GCC_ATOMICS 1
#define ENABLE_CYCLE_COUNTER 1
@@ -196,5 +197,16 @@ static inline uint32_t arch_cycle_count(void)
#endif
}
/* use the cpu local thread context pointer to store current_thread */
static inline struct thread *get_current_thread(void)
{
return (struct thread *)ARM64_READ_SYSREG(tpidr_el1);
}
static inline void set_current_thread(struct thread *t)
{
ARM64_WRITE_SYSREG(tpidr_el1, (uint64_t)t);
}
#endif // ASSEMBLY

View File

@@ -53,6 +53,8 @@ static void initial_thread_func(void)
{
int ret;
thread_t *current_thread = get_current_thread();
LTRACEF("initial_thread_func: thread %p calling %p with arg %p\n", current_thread, current_thread->entry, current_thread->arg);
/* exit the implicit critical section we're within */

View File

@@ -1,5 +1,6 @@
/*
* Copyright (c) 2009 Corey Tabaka
* Copyright (c) 2014 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
@@ -20,8 +21,8 @@
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __ARCH_X86_OPS_H
#define __ARHC_X86_OPS_H
#ifndef __ARCH_X86_64_OPS_H
#define __ARCH_X86_64_OPS_H
#include <compiler.h>
@@ -96,6 +97,19 @@ static inline uint32_t arch_cycle_count(void)
return timestamp;
}
/* use a global pointer to store the current_thread */
extern struct thread *_current_thread;
static inline struct thread *get_current_thread(void)
{
return _current_thread;
}
static inline void set_current_thread(struct thread *t)
{
_current_thread = t;
}
#endif // !ASSEMBLY
#endif

View File

@@ -18,7 +18,7 @@ MODULE_SRCS += \
$(LOCAL_DIR)/descriptor.c
# set the default toolchain to x86 elf and set a #define
TOOLCHAIN_PREFIX ?=
TOOLCHAIN_PREFIX ?= x86_64-elf-
LIBGCC := $(shell $(TOOLCHAIN_PREFIX)gcc $(CFLAGS) -print-libgcc-file-name)
#$(info LIBGCC = $(LIBGCC))

View File

@@ -1,6 +1,7 @@
/*
* Copyright (c) 2009 Corey Tabaka
* Copyright (c) 2014 Intel Corporation
* Copyright (c) 2014 Intel Corporation
* Copyright (c) 2014 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
@@ -36,6 +37,9 @@ struct context_switch_frame {
uint64_t rip;
};
/* we're uniprocessor at this point for x86-64, so store a global pointer to the current thread */
struct thread *_current_thread;
static void initial_thread_func(void) __NO_RETURN;
static void initial_thread_func(void)
{
@@ -44,7 +48,7 @@ static void initial_thread_func(void)
/* exit the implicit critical section we're within */
exit_critical_section();
ret = current_thread->entry(current_thread->arg);
ret = _current_thread->entry(_current_thread->arg);
thread_exit(ret);
}

View File

@@ -1,5 +1,6 @@
/*
* Copyright (c) 2009 Corey Tabaka
* Copyright (c) 2014 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
@@ -96,6 +97,19 @@ static inline uint32_t arch_cycle_count(void)
return timestamp;
}
/* use a global pointer to store the current_thread */
extern struct thread *_current_thread;
static inline struct thread *get_current_thread(void)
{
return _current_thread;
}
static inline void set_current_thread(struct thread *t)
{
_current_thread = t;
}
#endif // !ASSEMBLY
#endif

View File

@@ -1,5 +1,6 @@
/*
* Copyright (c) 2009 Corey Tabaka
* Copyright (c) 2014 Travis Geiselbrecht
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
@@ -39,6 +40,9 @@ struct context_switch_frame {
uint32_t eip;
};
/* we're uniprocessor at this point for x86, so store a global pointer to the current thread */
struct thread *_current_thread;
extern void x86_context_switch(addr_t *old_sp, addr_t new_sp);
static void initial_thread_func(void) __NO_RETURN;
@@ -46,15 +50,15 @@ static void initial_thread_func(void)
{
int ret;
// dprintf("initial_thread_func: thread %p calling %p with arg %p\n", current_thread, current_thread->entry, current_thread->arg);
// dump_thread(current_thread);
// dprintf("initial_thread_func: thread %p calling %p with arg %p\n", _current_thread, _current_thread->entry, _current_thread->arg);
// dump_thread(_current_thread);
/* exit the implicit critical section we're within */
exit_critical_section();
ret = current_thread->entry(current_thread->arg);
ret = _current_thread->entry(_current_thread->arg);
// dprintf("initial_thread_func: thread %p exiting with %d\n", current_thread, ret);
// dprintf("initial_thread_func: thread %p exiting with %d\n", _current_thread, ret);
thread_exit(ret);
}