/* * hal_special.c - implementation of TLS API for x86_64 * * Copyright (c) 2017 Maxime Villard * * This file is part of ALMOS-MKH. * * ALMOS-MKH is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2.0 of the License. * * ALMOS-MKH is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with ALMOS-MKH.; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include struct thread_s; typedef struct cpu_info { void *ci_self; uint32_t ci_gid; uint32_t ci_lid; struct thread_s *ci_thr; } cpu_info_t; cpu_info_t cpu0 __in_kdata; cpu_info_t *curcpu() { cpu_info_t *ci; __asm volatile("movq %%gs:%1, %0" : "=r" (ci) : "m" (*(cpu_info_t * const *)offsetof(cpu_info_t, ci_self))); return ci; } static void hal_tls_load_cpu(cpu_info_t *ci) { wrmsr(MSR_FSBASE, 0); wrmsr(MSR_GSBASE, (uint64_t)ci); wrmsr(MSR_KERNELGSBASE, 0); } void hal_tls_init_cpu0() { cpu_info_t *ci = &cpu0; memset(ci, 0, sizeof(cpu_info_t)); ci->ci_self = ci; ci->ci_gid = hal_lapic_gid(); ci->ci_lid = 0; /* XXX */ hal_tls_load_cpu(ci); } gid_t hal_get_gid() { return curcpu()->ci_gid; } cycle_t hal_time_stamp() { return rdtsc(); } uint64_t hal_get_cycles() { uint64_t cycles; core_t *core = CURRENT_THREAD->core; /* * Put the value of the TSC everywhere */ cycles = rdtsc(); core->time_stamp = cycles; core->cycles = cycles; return cycles; } struct thread_s *hal_get_current_thread() { return curcpu()->ci_thr; } void hal_set_current_thread( struct thread_s * thread ) { curcpu()->ci_thr = thread; } /* -------------------------------------------------------------------------- */ void hal_fpu_enable() { x86_panic((char *)__func__); } void hal_fpu_disable() { x86_panic((char *)__func__); } uint32_t hal_get_stack() { x86_panic((char *)__func__); return 0; } uint32_t hal_set_stack( void * new_val ) { x86_panic((char *)__func__); return 0; } uint32_t hal_get_bad_vaddr() { x86_panic((char *)__func__); return 0; } uint32_t hal_uncached_read( uint32_t * ptr ) { x86_panic((char *)__func__); return 0; } void hal_invalid_dcache_line( void * ptr ) { x86_panic((char *)__func__); } void hal_fence() { mfence(); } void hal_rdbar() { x86_panic((char *)__func__); } void hal_core_sleep() { x86_panic((char *)__func__); } void hal_fixed_delay( uint32_t delay ) { x86_panic((char *)__func__); } void hal_get_mmu_excp( intptr_t * mmu_ins_excp_code, intptr_t * mmu_ins_bad_vaddr, intptr_t * mmu_dat_excp_code, intptr_t * mmu_dat_bad_vaddr ) { x86_panic((char *)__func__); }