diff --git a/src/libsys/cop0.c b/src/libsys/cop0.c new file mode 100644 index 0000000..beca1ad --- /dev/null +++ b/src/libsys/cop0.c @@ -0,0 +1,150 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +#include "cop0.h" + +// --------------------------------------------------------------------------------- +// MIPS specific +// --------------------------------------------------------------------------------- +uint32_t CP0_SR_read(void) +{ + uint32_t result; + + __asm__ + ( + "mfc0 %[val], $12\n" + : [val] "=r" (result) + ); + + return result; +} + +void CP0_SR_write(uint32_t val) +{ + __asm__ + ( + "mtc0 %[val], $12\n" + : /* no output */ + : [val] "r" (val) + ); +} + +uint32_t CP0_CR_read(void) +{ + uint32_t result; + + __asm__ + ( + "mfc0 %[val], $13\n" + : [val] "=r" (result) + ); + + return result; +} + +void CP0_CR_write(uint32_t val) +{ + __asm__ + ( + "mtc0 %[val], $13\n" + : + : [val] "r" (val) + ); +} + +uint32_t CP0_TR_read(void) +{ + uint32_t result; + + __asm__ + ( + "mfc0 %[val], $31\n" + : [val] "=r" (result) + ); + + return result; +} + +void CP0_TR_write(uint32_t val) +{ + __asm__ + ( + "mtc0 %[val], $31\n" + : + : [val] "r" (val) + ); +} + +uint32_t CP0_PRID_read(void) +{ + uint32_t result; + + __asm__ + ( + "mfc0 %[val], $15\n" + : [val] "=r" (result) + ); + + return result; +} + +void CP0_TR_write_ptr(uint32_t* pPtr) +{ + __asm__ + ( + "swc0 $31, 0(%[pPtr])\n" + : + : [pPtr] "r" (pPtr) + ); +} + +void CP0_TR_read_ptr(uint32_t* pPtr) +{ + __asm__ + ( + "lwc0 $31, 0(%[pPtr])\n" + : + : [pPtr] "r" (pPtr) + ); +} + +void ICACHE_invalidate_all(void) +{ + __asm__ + ( + "cop0 32\n" + ); +} + +void ICACHE_invalidate_at(uint32_t* pPtr) +{ + __asm__ + ( + "mtc0 %[pPtr], $31\n" + "cop0 33\n" + : + : [pPtr] "r" (pPtr) + ); +} + +void DCACHE_invalidate_all(void) +{ + __asm__ + ( + "cop0 34\n" + ); +} + +void DCACHE_invalidate_at(uint32_t* pPtr) +{ + __asm__ + ( + "mtc0 %[pPtr], $31\n" + "cop0 35\n" + : + : [pPtr] "r" (pPtr) + ); +} diff --git a/src/libsys/cop0.h b/src/libsys/cop0.h new file mode 100644 index 0000000..fa613e0 --- /dev/null +++ b/src/libsys/cop0.h @@ -0,0 +1,96 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/* + * File: cop0.h + * Author: jens + * + * Created on 12. Januar 2017, 16:07 + */ + +#ifndef COP0_H +#define COP0_H + +#include + +// --------------------------------------------------------- +// Chip registers +// --------------------------------------------------------- +// COP0 registers +#define COP0_REG_INVAT_POINTER 31 + +// COP0 instructions +#define COP0_INSTR_INVALL_ICACHE 32 +#define COP0_INSTR_INVAT_ICACHE 33 +#define COP0_INSTR_INVALL_DCACHE 34 +#define COP0_INSTR_INVAT_DCACHE 35 + +#define CP0_read(idx) \ +({ \ + uint32_t result; \ + __asm__ __volatile__ \ + ( \ + "mfc0\t%0,$"#idx"\n" \ + : "=r" (result) \ + ); \ + result; \ +}) + +#define CP0_write(idx, val) \ +({ \ + __asm__ __volatile__ \ + ( \ + "mtc0\t%0,$"#idx"\n" \ + "nop\n" \ + : /* no output */ \ + : "r" (val) \ + ); \ +}) + +#define CP0_TLBR \ +({ \ + __asm__ __volatile__ \ + ( \ + "tlbr\n" \ + : /* no output */ \ + : /* no input */ \ + ); \ +}) + +#define CP0_TLBWI \ +({ \ + __asm__ __volatile__ \ + ( \ + "tlbwi\n" \ + : /* no output */ \ + : /* no input */ \ + ); \ +}) + +#ifdef __cplusplus +extern "C" { +#endif + +uint32_t CP0_SR_read(void); +void CP0_SR_write(uint32_t val); +uint32_t CP0_CR_read(void); +void CP0_CR_write(uint32_t val); +uint32_t CP0_PRID_read(void); +uint32_t CP0_TR_read(void); +void CP0_TR_write(uint32_t val); +void CP0_TR_write_ptr(uint32_t* pPtr); +void CP0_TR_read_ptr(uint32_t* pPtr); +void ICACHE_invalidate_all(void); +void ICACHE_invalidate_at(uint32_t* pPtr); +void DCACHE_invalidate_all(void); +void DCACHE_invalidate_at(uint32_t* pPtr); + +#ifdef __cplusplus +} +#endif + +#endif /* COP0_H */ +