1// Copyright 2016 The Fuchsia Authors
2//
3// Use of this source code is governed by a MIT-style
4// license that can be found in the LICENSE file or at
5// https://opensource.org/licenses/MIT
6
7#pragma once
8
9__BEGIN_CDECLS
10
11/* use the cpu local thread context pointer to store current_thread */
12static inline struct thread* get_current_thread(void) {
13#ifdef __clang__
14    // Clang with --target=aarch64-fuchsia -mcmodel=kernel reads
15    // TPIDR_EL1 for __builtin_thread_pointer (instead of the usual
16    // TPIDR_EL0 for user mode).  Using the intrinsic instead of asm
17    // lets the compiler understand what it's doing a little better,
18    // which conceivably could let it optimize better.
19    char* tp = (char*)__builtin_thread_pointer();
20#else
21    char* tp = (char*)ARM64_READ_SYSREG(tpidr_el1);
22#endif
23    tp -= offsetof(struct thread, arch.thread_pointer_location);
24    return (struct thread*)tp;
25}
26
27static inline void set_current_thread(struct thread* t) {
28    ARM64_WRITE_SYSREG(tpidr_el1, (uint64_t)&t->arch.thread_pointer_location);
29}
30
31__END_CDECLS
32