[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:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user