1 // Copyright 2016 The Fuchsia Authors 2 // Copyright (c) 2014 Travis Geiselbrecht 3 // 4 // Use of this source code is governed by a MIT-style 5 // license that can be found in the LICENSE file or at 6 // https://opensource.org/licenses/MIT 7 8 #pragma once 9 10 #define CURRENT_PERCPU_PTR_OFFSET 16 11 12 #ifndef __ASSEMBLER__ 13 14 #include <assert.h> 15 #include <arch/arm64/registers.h> 16 #include <stddef.h> 17 #include <sys/types.h> 18 #include <zircon/compiler.h> 19 #include <zircon/tls.h> 20 21 __BEGIN_CDECLS 22 23 struct fpstate { 24 uint32_t fpcr; 25 uint32_t fpsr; 26 uint64_t regs[64]; 27 }; 28 29 struct arm64_percpu; 30 31 struct arch_thread { 32 // The compiler (when it's Clang with -mcmodel=kernel) knows 33 // the position of these two fields relative to TPIDR_EL1, 34 // which is what __builtin_thread_pointer() returns. TPIDR_EL1 35 // points just past these, i.e. to &abi[1]. 36 uintptr_t stack_guard; 37 vaddr_t unsafe_sp; 38 union { 39 char thread_pointer_location; 40 vaddr_t sp; 41 }; 42 43 // Debugger access to userspace general regs while suspended or stopped 44 // in an exception. 45 // The regs are saved on the stack and then a pointer is stored here. 46 // NULL if not suspended or stopped in an exception. 47 struct arm64_iframe_long* suspended_general_regs; 48 49 // Point to the current cpu pointer when the thread is running, used to 50 // restore x18 on exception entry. Swapped on context switch. 51 struct arm64_percpu* current_percpu_ptr; 52 53 // if non-NULL, address to return to on data fault 54 void* data_fault_resume; 55 56 // saved fpu state 57 struct fpstate fpstate; 58 59 // |track_debug_state| tells whether the kernel should keep track of the whole debug state for 60 // this thread. Normally this is set explicitly by an user that wants to make use of HW 61 // breakpoints or watchpoints. 62 // Userspace can still read the complete |debug_state| even if |track_debug_state| is false. 63 bool track_debug_state; 64 arm64_debug_state_t debug_state; 65 }; 66 67 #define thread_pointer_offsetof(field) \ 68 ((int)offsetof(struct arch_thread, field) - \ 69 (int)offsetof(struct arch_thread, thread_pointer_location)) 70 71 static_assert( 72 thread_pointer_offsetof(stack_guard) == ZX_TLS_STACK_GUARD_OFFSET, 73 "stack_guard field in wrong place"); 74 static_assert( 75 thread_pointer_offsetof(unsafe_sp) == ZX_TLS_UNSAFE_SP_OFFSET, 76 "unsafe_sp field in wrong place"); 77 static_assert( 78 thread_pointer_offsetof(current_percpu_ptr) == CURRENT_PERCPU_PTR_OFFSET, 79 "per cpu ptr offset in wrong place"); 80 81 __END_CDECLS 82 83 #endif // __ASSEMBLER__ 84