/* * hal_special.c - implementation of Generic Special Register Access API for TSAR-MIPS32 * * Author Ghassan Almaless (2008,2009,2010,2011,2012) * Alain Greiner (2016) * * Copyright (c) UPMC Sorbonne Universites * * 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 /**** Forward declarations ****/ struct thread_s; /////////////////// gid_t hal_get_gid() { uint32_t proc_id; asm volatile ("mfc0 %0, $15, 1" : "=&r" (proc_id)); return (proc_id & 0x3FF); // 4/4/2 format for TSAR } ///////////////////////// uint32_t hal_time_stamp() { uint32_t cycles; asm volatile ("mfc0 %0, $9 " : "=&r" (cycles)); return cycles; } ////////////////////////////////////////// struct thread_s * hal_get_current_thread() { void * thread_ptr; asm volatile ( "mfc0 %0, $4, 2 \n" : "=&r" (thread_ptr) ); return thread_ptr; } /////////////////////////////////////////////////////// void hal_set_current_thread( struct thread_s * thread ) { asm volatile ( "mtc0 %0, $4, 2 \n" : : "r" (thread) ); } ///////////////////// void hal_fpu_enable() { asm volatile ( ".set noat \n" "lui $27, 0x2000 \n" "mfc0 $1, $12 \n" "or $27, $1, $27 \n" "mtc0 $27, $12 \n" ".set at \n" ); } ////////////////////// void hal_fpu_disable() { asm volatile ( ".set noat \n" "lui $27, 0xDFFF \n" "ori $27, $27, 0xFFFF \n" "mfc0 $1, $12 \n" "and $27, $1, $27 \n" "mtc0 $27, $12 \n" ".set at \n"); } //////////////////////// uint32_t hal_get_stack() { register uint32_t sp; asm volatile ( "or %0, $0, $29 \n" : "=&r" (sp) ); return sp; } //////////////////////////////////////// uint32_t hal_set_stack( void * new_val ) { register uint32_t sp; asm volatile ( "or %0, $0, $29 \n" "or $29, $0, %1 \n" : "=&r" (sp) : "r" (new_val) ); return sp; } //////////////////////////// uint32_t hal_get_bad_vaddr() { register uint32_t bad_va; asm volatile ( "mfc0 %0, $8 \n" : "=&r" (bad_va) ); return bad_va; } //////////////////////////////////////////// uint32_t hal_uncached_read( uint32_t * ptr ) { register uint32_t val; asm volatile ( "ll %0, (%1) \n" : "=&r"(val) : "r" (ptr) ); return val; } ////////////////////////////////////////// void hal_invalid_dcache_line( void * ptr ) { asm volatile ( "cache %0, (%1) \n" "sync \n" : : "i" (0x11) , "r" (ptr) ); } ////////////////// void hal_wbflush() { asm volatile ( "sync \n":: ); } //////////////// void hal_rdbar() { asm volatile( "" ::: "memory" ); } ///////////////////// void hal_core_sleep() { asm volatile ("wait \n"::); } ////////////////////////////////////// void hal_fixed_delay( uint32_t delay ) { asm volatile ( "1: \n" "or $27, %0, $0 \n" "addi $27, $27, -1 \n" "bne $27, $0, 1b \n" "nop \n" : : "r" (delay) : "$27" ); } ////////////////////////////////////////////////// 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 ) { asm volatile ( "mfc2 %0, $11 \n" "mfc2 %1, $13 \n" "mfc2 %2, $12 \n" "mfc2 %3, $14 \n" : "=&r"(mmu_ins_excp_code), "=&r"(mmu_ins_bad_vaddr), "=&r"(mmu_dat_excp_code), "=&r"(mmu_dat_bad_vaddr) ); }