mips.h 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  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) ({ \
  45. __asm__ __volatile__ ("mtc0 %z0, " __XSTRING(reg) "\n" \
  46. : : "Jr" ((uint32_t)(val))); })
  47. #define mips_read_status() __mips_read_32b_c0(CP0_STATUS)
  48. #define mips_read_count() __mips_read_32b_c0(CP0_COUNT)
  49. #define mips_reset_count() __mips_write_32b_c0(CP0_COUNT, 0)
  50. #define mips_set_status(val) __mips_write_32b_c0(CP0_STATUS, val)
  51. #define mips_compare_t0(val) __mips_write_32b_c0(CP0_COMPARESTATUS, val)
  52. #define nop(void) ({ __asm__ __volatile__ ("nop");})
  53. static __always_inline bool irq_lock(void)
  54. {
  55. uint32_t status = read_status();
  56. if (status & ST0_IE) {
  57. write_status(status & (~ST0_IE));
  58. return true;
  59. }
  60. return false;
  61. }
  62. static __always_inline void irq_unlock(void)
  63. {
  64. uint32_t status = read_status();
  65. write_status(status | ST0_IE);
  66. }
  67. static __always_inline void wait(void)
  68. {
  69. irq_unlock();
  70. __asm__ __volatile__ ("wait");
  71. }
  72. #endif