|
|
@@ -0,0 +1,85 @@
|
|
|
+#ifndef MIPS32_H
|
|
|
+#define MIPS32_H
|
|
|
+
|
|
|
+#include <stdbool.h>
|
|
|
+#include <sys/cdefs.h>
|
|
|
+
|
|
|
+#define CP0_BADVADDR $8
|
|
|
+#define CP0_COUNT $9
|
|
|
+#define CP0_COMPARE $11
|
|
|
+#define CP0_STATUS $12
|
|
|
+#define CP0_CAUSE $13
|
|
|
+#define CP0_EPC $14
|
|
|
+#define CP0_ID $15
|
|
|
+
|
|
|
+#define ST0_IE 0x0000001
|
|
|
+#define ST0_EXL 0x0000002
|
|
|
+#define ST0_ERL 0x0000004
|
|
|
+#define ST0_IP0 0x0000100
|
|
|
+#define ST0_BEV 0x0040000
|
|
|
+
|
|
|
+#define relax() __compiler_membar()
|
|
|
+
|
|
|
+#define sync() __asm__ __volatile__( \
|
|
|
+ ".set push\n\t" \
|
|
|
+ ".set noreorder\n\t" \
|
|
|
+ ".set mips32\n\t" \
|
|
|
+ "sync\n\t" \
|
|
|
+ ".set pop" \
|
|
|
+ ": : : "memory")
|
|
|
+
|
|
|
+#define __mb() __asm__ __volatile__ ( \
|
|
|
+ ".set noreorder\n\t" \
|
|
|
+ "nop;nop;nop;nop\n\t" \
|
|
|
+ ".set reorder" \
|
|
|
+ ": : : "memory")
|
|
|
+
|
|
|
+#define __mips_read_32b_c0(reg) ({ \
|
|
|
+ uint32_t value; \
|
|
|
+ __asm__ __volatile__("mfc0 %0, " __XSTRING(reg) "\n" \
|
|
|
+ : "=r" (val)); \
|
|
|
+ val; })
|
|
|
+
|
|
|
+#define __mips_read_32b_c0_sel(source, sel) ({ _
|
|
|
+ uint32_t value; \
|
|
|
+ __asm__ __volatile__( \
|
|
|
+ ".set push\n\t" \
|
|
|
+ ".set mips32\n\t" \
|
|
|
+ "mfc0 %0, " #source ", " #sek "\n\t" \
|
|
|
+ ".set pop" \
|
|
|
+ : "=r" (val)); \
|
|
|
+ val; })
|
|
|
+
|
|
|
+#define __mips_write_32b_c0(reg, val) ({ __asm__ __volatile__ ("mtc0 %z0, " __XSTRING(reg) "\n" \
|
|
|
+ : : "Jr" ((uint32_t)(val))); })
|
|
|
+
|
|
|
+#define mips_read_status() __mips_read_32b_c0(CP0_STATUS)
|
|
|
+#define mips_read_count() __mips_read_32b_c0(CP0_COUNT)
|
|
|
+#define mips_reset_count() __mips_write_32b_c0(CP0_COUNT, 0)
|
|
|
+#define mips_set_status(val) __mips_write_32b_c0(CP0_STATUS, val)
|
|
|
+#define mips_compare_t0(val) __mips_write_32b_c0(CP0_COMPARESTATUS, val)
|
|
|
+#define nop(void) ({ __asm__ __volatile__ ("nop");})
|
|
|
+
|
|
|
+static __always_inline bool irq_lock(void)
|
|
|
+{
|
|
|
+ uint32_t status = read_status();
|
|
|
+ if (status & ST0_IE) {
|
|
|
+ write_status(status & (~ST0_IE));
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+static __always_inline void irq_unlock(void)
|
|
|
+{
|
|
|
+ uint32_t status = read_status();
|
|
|
+ write_status(status | ST0_IE);
|
|
|
+}
|
|
|
+
|
|
|
+static __always_inline void wait(void)
|
|
|
+{
|
|
|
+ irq_unlock();
|
|
|
+ __asm__ __volatile__ ("wait");
|
|
|
+}
|
|
|
+#endif
|