blob: c85d6a58598276f0d05e90daa8d0c46649e99a19 [file] [log] [blame]
// Copyright 2016 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#pragma once
__BEGIN_CDECLS
/* use the cpu local thread context pointer to store current_thread */
static inline struct thread* get_current_thread(void) {
#ifdef __clang__
// Clang with --target=aarch64-fuchsia -mcmodel=kernel reads
// TPIDR_EL1 for __builtin_thread_pointer (instead of the usual
// TPIDR_EL0 for user mode). Using the intrinsic instead of asm
// lets the compiler understand what it's doing a little better,
// which conceivably could let it optimize better.
char* tp = (char*)__builtin_thread_pointer();
#else
char* tp = (char*)__arm_rsr64("tpidr_el1");
#endif
tp -= offsetof(struct thread, arch.thread_pointer_location);
return (struct thread*)tp;
}
static inline void set_current_thread(struct thread* t) {
__arm_wsr64("tpidr_el1", (uint64_t)&t->arch.thread_pointer_location);
__isb(ARM_MB_SY);
}
__END_CDECLS