/** * \file cpu.h * \date March 10, 2014 * \author Cesar Fuguet * \brief MIPS32 processor core function definitions */ #ifndef _CPU_H #define _CPU_H #include #include #define CLUSTER(x,y) (((x) << Y_WIDTH) | (y)) #define CLUSTER_ID_BITS (X_WIDTH + Y_WIDTH) #define CLUSTER_OFFSET_BITS (40-CLUSTER_ID_BITS) /* * Inline functions definition */ static inline unsigned int cpu_procid() { register uint32_t ret asm("v0"); asm volatile ("mfc0 %[ret], $15,1" : [ret] "=r"(ret)); return (ret & 0x3FF); } static inline unsigned int cpu_cluster() { return (cpu_procid() / NB_PROCS_MAX); } static inline unsigned int cpu_x() { return (cpu_cluster() >> Y_WIDTH); } static inline unsigned int cpu_y() { return (cpu_cluster() & ((1 << X_WIDTH) - 1)); } static inline unsigned int cpu_l() { return (cpu_procid() % NB_PROCS_MAX); } static inline unsigned int cpu_time() { register uint32_t ret asm("v0"); asm volatile ("mfc0 %[ret], $9,0" : [ret] "=r"(ret)); return ret; }; static inline unsigned int cpu_get_sp() { register unsigned int ret asm("v0"); asm volatile ("move %[ret], $29" : [ret] "=r"(ret)); return ret; } static inline void cpu_set_sp(uint32_t sp) { asm volatile ("move $29, %[addr] \n" : /* no output */ : [addr] "r"(sp) : "memory"); } static inline void cpu_wait() { asm volatile ("wait"); } static inline void cpu_sync() { asm volatile ("sync":::"memory"); } static inline void cpu_sleep(uint32_t cycles) { asm volatile (".set noreorder \n" "1: \n" "bnez %[c], 1b \n" "addiu %[c], %[c], -1 \n" ".set reorder \n" : /* no output */ : [c] "r"(cycles)); } static inline void cpu_set_ptpr(uint32_t ptpr) { asm volatile ("mtc2 %[ptpr], $0\n" : /* no output */ : [ptpr] "r"(ptpr) : "memory"); } static inline uint32_t cpu_get_ptpr() { register uint32_t ret asm("v0"); asm volatile ("mfc2 %[ret], $0\n" : [ret] "=r"(ret)); return ret; } static inline uint32_t cpu_get_mmu_detr() { register uint32_t ret asm("v0"); asm volatile ("mfc2 %[ret], $12\n" : [ret] "=r"(ret)); return ret; } static inline uint32_t cpu_get_cr_exccode() { register uint32_t ret asm("v0"); asm volatile ("mfc0 %[ret], $13\n" : [ret] "=r"(ret)); return ((ret >> 2) & 0x1F); } static inline void cpu_set_wdt_max(uint32_t max) { asm volatile ("mtc2 %[max], $26\n" : : [max] "r"(max) : "memory"); } static inline uint32_t cpu_get_wdt_max() { register uint32_t ret asm("v0"); asm volatile ("mfc2 %[ret], $12\n" : [ret] "=r"(ret)); return ret; } #endif /* _CPU_H */ /* * vim: tabstop=4 : softtabstop=4 : shiftwidth=4 : expandtab */