mips.h 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. #ifndef MIPS32_H
  2. #define MIPS32_H
  3. #include <stdbool.h>
  4. #include <sys/cdefs.h>
  5. #define CP0_BADVADDR $8
  6. #define CP0_COUNT $9
  7. #define CP0_COMPARE $11
  8. #define CP0_STATUS $12
  9. #define CP0_CAUSE $13
  10. #define CP0_EPC $14
  11. #define CP0_ID $15
  12. #define ST0_IE 0x0000001
  13. #define ST0_EXL 0x0000002
  14. #define ST0_ERL 0x0000004
  15. #define ST0_IP0 0x0000100
  16. #define ST0_BEV 0x0040000
  17. #define relax() __compiler_membar()
  18. #define sync() __asm__ __volatile__( \
  19. ".set push\n\t" \
  20. ".set noreorder\n\t" \
  21. ".set mips32\n\t" \
  22. "sync\n\t" \
  23. ".set pop" \
  24. ": : : "memory")
  25. #define __mb() __asm__ __volatile__ ( \
  26. ".set noreorder\n\t" \
  27. "nop;nop;nop;nop\n\t" \
  28. ".set reorder" \
  29. ": : : "memory")
  30. #define __mips_read_32b_c0(reg) ({ \
  31. uint32_t value; \
  32. __asm__ __volatile__("mfc0 %0, " __XSTRING(reg) "\n" \
  33. : "=r" (val)); \
  34. val; })
  35. #define __mips_read_32b_c0_sel(source, sel) ({ _
  36. uint32_t value; \
  37. __asm__ __volatile__( \
  38. ".set push\n\t" \
  39. ".set mips32\n\t" \
  40. "mfc0 %0, " #source ", " #sek "\n\t" \
  41. ".set pop" \
  42. : "=r" (val)); \
  43. val; })
  44. #define __mips_write_32b_c0(reg, val) ({ __asm__ __volatile__ ("mtc0 %z0, " __XSTRING(reg) "\n" \
  45. : : "Jr" ((uint32_t)(val))); })
  46. #define mips_read_status() __mips_read_32b_c0(CP0_STATUS)
  47. #define mips_read_count() __mips_read_32b_c0(CP0_COUNT)
  48. #define mips_reset_count() __mips_write_32b_c0(CP0_COUNT, 0)
  49. #define mips_set_status(val) __mips_write_32b_c0(CP0_STATUS, val)
  50. #define mips_compare_t0(val) __mips_write_32b_c0(CP0_COMPARESTATUS, val)
  51. #define nop(void) ({ __asm__ __volatile__ ("nop");})
  52. static __always_inline bool irq_lock(void)
  53. {
  54. uint32_t status = read_status();
  55. if (status & ST0_IE) {
  56. write_status(status & (~ST0_IE));
  57. return true;
  58. }
  59. return false;
  60. }
  61. static __always_inline void irq_unlock(void)
  62. {
  63. uint32_t status = read_status();
  64. write_status(status | ST0_IE);
  65. }
  66. static __always_inline void wait(void)
  67. {
  68. irq_unlock();
  69. __asm__ __volatile__ ("wait");
  70. }
  71. #endif