CommandProcessor.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. // Copyright 2008 Dolphin Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include <atomic>
  5. #include "Common/CommonTypes.h"
  6. #include "Common/Flag.h"
  7. class PointerWrap;
  8. namespace MMIO
  9. {
  10. class Mapping;
  11. }
  12. namespace Core
  13. {
  14. class System;
  15. }
  16. namespace CoreTiming
  17. {
  18. struct EventType;
  19. }
  20. namespace CommandProcessor
  21. {
  22. struct SCPFifoStruct
  23. {
  24. // fifo registers
  25. std::atomic<u32> CPBase = 0;
  26. std::atomic<u32> CPEnd = 0;
  27. u32 CPHiWatermark = 0;
  28. u32 CPLoWatermark = 0;
  29. std::atomic<u32> CPReadWriteDistance = 0;
  30. std::atomic<u32> CPWritePointer = 0;
  31. std::atomic<u32> CPReadPointer = 0;
  32. std::atomic<u32> CPBreakpoint = 0;
  33. std::atomic<u32> SafeCPReadPointer = 0;
  34. std::atomic<u32> bFF_GPLinkEnable = 0;
  35. std::atomic<u32> bFF_GPReadEnable = 0;
  36. std::atomic<u32> bFF_BPEnable = 0;
  37. std::atomic<u32> bFF_BPInt = 0;
  38. std::atomic<u32> bFF_Breakpoint = 0;
  39. std::atomic<u32> bFF_LoWatermarkInt = 0;
  40. std::atomic<u32> bFF_HiWatermarkInt = 0;
  41. std::atomic<u32> bFF_LoWatermark = 0;
  42. std::atomic<u32> bFF_HiWatermark = 0;
  43. void Init();
  44. void DoState(PointerWrap& p);
  45. };
  46. // internal hardware addresses
  47. enum
  48. {
  49. STATUS_REGISTER = 0x00,
  50. CTRL_REGISTER = 0x02,
  51. CLEAR_REGISTER = 0x04,
  52. PERF_SELECT = 0x06,
  53. FIFO_TOKEN_REGISTER = 0x0E,
  54. FIFO_BOUNDING_BOX_LEFT = 0x10,
  55. FIFO_BOUNDING_BOX_RIGHT = 0x12,
  56. FIFO_BOUNDING_BOX_TOP = 0x14,
  57. FIFO_BOUNDING_BOX_BOTTOM = 0x16,
  58. FIFO_BASE_LO = 0x20,
  59. FIFO_BASE_HI = 0x22,
  60. FIFO_END_LO = 0x24,
  61. FIFO_END_HI = 0x26,
  62. FIFO_HI_WATERMARK_LO = 0x28,
  63. FIFO_HI_WATERMARK_HI = 0x2a,
  64. FIFO_LO_WATERMARK_LO = 0x2c,
  65. FIFO_LO_WATERMARK_HI = 0x2e,
  66. FIFO_RW_DISTANCE_LO = 0x30,
  67. FIFO_RW_DISTANCE_HI = 0x32,
  68. FIFO_WRITE_POINTER_LO = 0x34,
  69. FIFO_WRITE_POINTER_HI = 0x36,
  70. FIFO_READ_POINTER_LO = 0x38,
  71. FIFO_READ_POINTER_HI = 0x3A,
  72. FIFO_BP_LO = 0x3C,
  73. FIFO_BP_HI = 0x3E,
  74. XF_RASBUSY_L = 0x40,
  75. XF_RASBUSY_H = 0x42,
  76. XF_CLKS_L = 0x44,
  77. XF_CLKS_H = 0x46,
  78. XF_WAIT_IN_L = 0x48,
  79. XF_WAIT_IN_H = 0x4a,
  80. XF_WAIT_OUT_L = 0x4c,
  81. XF_WAIT_OUT_H = 0x4e,
  82. VCACHE_METRIC_CHECK_L = 0x50,
  83. VCACHE_METRIC_CHECK_H = 0x52,
  84. VCACHE_METRIC_MISS_L = 0x54,
  85. VCACHE_METRIC_MISS_H = 0x56,
  86. VCACHE_METRIC_STALL_L = 0x58,
  87. VCACHE_METRIC_STALL_H = 0x5A,
  88. CLKS_PER_VTX_IN_L = 0x60,
  89. CLKS_PER_VTX_IN_H = 0x62,
  90. CLKS_PER_VTX_OUT = 0x64,
  91. };
  92. enum
  93. {
  94. INT_CAUSE_CP = 0x800
  95. };
  96. // Fifo Status Register
  97. union UCPStatusReg
  98. {
  99. struct
  100. {
  101. u16 OverflowHiWatermark : 1;
  102. u16 UnderflowLoWatermark : 1;
  103. u16 ReadIdle : 1;
  104. u16 CommandIdle : 1;
  105. u16 Breakpoint : 1;
  106. u16 : 11;
  107. };
  108. u16 Hex;
  109. UCPStatusReg() { Hex = 0; }
  110. UCPStatusReg(u16 _hex) { Hex = _hex; }
  111. };
  112. // Fifo Control Register
  113. union UCPCtrlReg
  114. {
  115. struct
  116. {
  117. u16 GPReadEnable : 1;
  118. u16 BPEnable : 1;
  119. u16 FifoOverflowIntEnable : 1;
  120. u16 FifoUnderflowIntEnable : 1;
  121. u16 GPLinkEnable : 1;
  122. u16 BPInt : 1;
  123. u16 : 10;
  124. };
  125. u16 Hex;
  126. UCPCtrlReg() { Hex = 0; }
  127. UCPCtrlReg(u16 _hex) { Hex = _hex; }
  128. };
  129. // Fifo Clear Register
  130. union UCPClearReg
  131. {
  132. struct
  133. {
  134. u16 ClearFifoOverflow : 1;
  135. u16 ClearFifoUnderflow : 1;
  136. u16 ClearMetrices : 1;
  137. u16 : 13;
  138. };
  139. u16 Hex;
  140. UCPClearReg() { Hex = 0; }
  141. UCPClearReg(u16 _hex) { Hex = _hex; }
  142. };
  143. constexpr u32 GetPhysicalAddressMask(bool is_wii)
  144. {
  145. // Physical addresses in CP seem to ignore some of the upper bits (depending on platform)
  146. // This can be observed in CP MMIO registers by setting to 0xffffffff and then reading back.
  147. return is_wii ? 0x1fffffff : 0x03ffffff;
  148. }
  149. class CommandProcessorManager
  150. {
  151. public:
  152. explicit CommandProcessorManager(Core::System& system);
  153. void Init();
  154. void DoState(PointerWrap& p);
  155. void RegisterMMIO(MMIO::Mapping* mmio, u32 base);
  156. void SetCPStatusFromGPU();
  157. void SetCPStatusFromCPU();
  158. void GatherPipeBursted();
  159. void UpdateInterrupts(u64 userdata);
  160. void UpdateInterruptsFromVideoBackend(u64 userdata);
  161. bool IsInterruptWaiting() const;
  162. void SetCpClearRegister();
  163. void SetCpControlRegister();
  164. void SetCpStatusRegister();
  165. void HandleUnknownOpcode(u8 cmd_byte, const u8* buffer, bool preprocess);
  166. // This one is shared between gfx thread and emulator thread.
  167. // It is only used by the Fifo and by the CommandProcessor.
  168. SCPFifoStruct& GetFifo() { return m_fifo; }
  169. private:
  170. SCPFifoStruct m_fifo;
  171. CoreTiming::EventType* m_event_type_update_interrupts = nullptr;
  172. // STATE_TO_SAVE
  173. UCPStatusReg m_cp_status_reg;
  174. UCPCtrlReg m_cp_ctrl_reg;
  175. UCPClearReg m_cp_clear_reg;
  176. u16 m_bbox_left = 0;
  177. u16 m_bbox_top = 0;
  178. u16 m_bbox_right = 0;
  179. u16 m_bbox_bottom = 0;
  180. u16 m_token_reg = 0;
  181. Common::Flag m_interrupt_set;
  182. Common::Flag m_interrupt_waiting;
  183. bool m_is_fifo_error_seen = false;
  184. Core::System& m_system;
  185. };
  186. } // namespace CommandProcessor