Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Dependency control scoreboard kernel
  3.  * Copyright © <2010>, Intel Corporation.
  4.  *
  5.  * This program is licensed under the terms and conditions of the
  6.  * Eclipse Public License (EPL), version 1.0.  The full text of the EPL is at
  7.  * http://www.opensource.org/licenses/eclipse-1.0.php.
  8.  *
  9.  */
  10. // Kernel name: scoreboard.asm
  11. //
  12. // Dependency control scoreboard kernel
  13. //
  14. //  $Revision: 16 $
  15. //  $Date: 10/18/06 4:10p $
  16. //
  17.  
  18. // ----------------------------------------------------
  19. //  Main: scoreboard
  20. // ----------------------------------------------------
  21. // ----------------------------------------------------
  22. //  Scoreboard structure
  23. // ----------------------------------------------------
  24. //
  25. //      1 DWORD per thread
  26. //
  27. //      Bit 31: "Checking" thread, i.e. an intra MB that sends "check dependency" message
  28. //      Bit 30: "Completed" thread. This bit set by an "update" message from intra/inter MB.
  29. //      Bits 29:28:     Must set to 0
  30. //      Bits 27:24:     EUID
  31. //      Bits 23:18: Reserved
  32. //      Bits 17:16: TID
  33. //      Bits 15:8:      X offset of current MB
  34. //      Bits 15:5:      Reserved
  35. //      Bits 4:0: 5 bits of available neighbor MB flags
  36.  
  37. .kernel scoreboard
  38. SCOREBOARD:
  39.  
  40. #ifdef _DEBUG
  41. // WA for FULSIM so we'll know which kernel is being debugged
  42. mov (1) acc0:ud 0xf0aa55a5:ud
  43. #endif
  44.  
  45. #include "header.inc"
  46. #include "scoreboard_header.inc"
  47.  
  48. //
  49. //  Now, begin source code....
  50. //
  51.  
  52. .code
  53.  
  54. #ifdef  AS_ENABLED
  55.         and.z.f0.1      (1)     NULLREG r0.2<0;1,0>:ud  TH_RES  // Is this a restarted thread previously interrupted?
  56.         (f0.1) jmpi     (1)     Scoreboard_Init
  57.  
  58.         #include "scoreboard_restore_AS.asm"
  59.  
  60.         jmpi (1)        Scoreboard_OpenGW
  61. Scoreboard_Init:
  62. #endif  // End AS_ENABLED
  63.  
  64. // Scoreboard must be initialized to 0xc000ffff, meaning all "completed"
  65. // And it also avoids message mis-handling for the first MB
  66.    $for(0; <32; 2) {
  67.         mov (16)        CMD_SB(%1)<1>   0xc000ffff:ud {Compr}
  68.         }
  69. #ifdef  DOUBLE_SB                                       // Scoreboard size needs to be doubled
  70.    $for(32; <64; 2) {
  71.         mov (16)        CMD_SB(%1)<1>   0xc000ffff:ud {Compr}
  72.         }
  73. #endif  // DOUBLE_SB
  74.  
  75. //----------------------------------------------------------
  76. //      Open message gateway for the scoreboard thread
  77. //
  78. //      RegBase = r4 (0x04)
  79. //      Gateway Size = 64 GRF registers (0x6)
  80. //      Dispatch ID = r0.20:ub
  81. //      Scoreboard Thread Key = 0
  82. //----------------------------------------------------------
  83. Scoreboard_OpenGW:
  84.     mov (8)     MSGHDRY0<1>:ud  0x00000000:ud                   // Initialize message header payload with 0
  85.  
  86.         // Send a message with register base RegBase=0x04(r4) and Gateway size = 0x6 = 64 GRF reg and Key = 0
  87.         // 000 00000100 00000 00000 110 00000000 ==> 0000 0000 1000 0000 0000 0110 0000 0000
  88. #ifdef  AS_ENABLED
  89.         add (1) MSGHDRY0.5<1>:ud r0.20:ub       0x00800700:ud   // Allocate 128 GRFs for message gateway - for SIP to send notification MSG
  90. #else
  91.   #ifdef        DOUBLE_SB
  92.         add (1) MSGHDRY0.5<1>:ud r0.20:ub       0x00800600:ud   // 64 GRF's for CTG-B
  93.   #else
  94.         add (1) MSGHDRY0.5<1>:ud r0.20:ub       0x00800500:ud   // 32 GRF's for CTG-A
  95.   #endif        // DOUBLE_SB
  96. #endif
  97.         send (8)        NULLREG  MSGHDRY0       null:ud    MSG_GW       OGWMSGDSC
  98.  
  99. //------------------------------------------------------------------------
  100. //      Send Thread Spawning Message to start dispatching macroblock threads
  101. //
  102. //------------------------------------------------------------------------
  103. #ifdef  AS_ENABLED
  104.         mov (8) acc0<1>:ud      CMD_SB(31)<8;8,1>                       // Ensure scoreboard data have been completely restored
  105. #endif  // End AS_ENABLED
  106.     mov (8)     MSGHDRY1<1>:ud          r0<8;8,1>:ud            // Initialize message header payload with R0
  107.     mov (1)     MSGHDRY1.4<1>:ud        0x00000400:ud           // Dispatch URB length = 1
  108.  
  109.         send (8)        NULLREG  MSGHDRY1       null:ud    TS   TSMSGDSC
  110.  
  111.     mov (8)     MSGHDRY0<1>:ud          0x00000000:ud           // Initialize message header payload with 0
  112.  
  113. //------------------------------------------------------------------------
  114. //      Scoreboard control data initialization
  115. //------------------------------------------------------------------------
  116. #ifdef  AS_ENABLED
  117.         or      (1)     cr0.1:ud        cr0.1:ud        AS_INT_EN               // Enable interrupt
  118.         (f0.1) jmpi     (1)     Scoreboard_State_Init   // Jump if not restarted thread
  119.  
  120.         // Restore scoreboard kernel control data to r1 - r3
  121.     mov (1)     m4.1:ud 64:ud                           // Starting r1
  122.     mov (1)     m4.2:ud 0x0002001f:ud           // for 3 registers
  123.     send (8)    r1.0<1>:ud      m4      null:ud DWBRMSGDSC_SC+0x00030000+AS_SAVE        // Restore r1 - r3
  124.         mov     (8)     a0.0<1>:uw      AR_SAVE<8;8,1>:uw                               // Restore all address registers
  125.  
  126. // Check whether all MBs have been decoded
  127.         cmp.e.f0.0 (1)  NULLREG TotalMB<0;1,0>:w        0:w     // Set "Last MB" flag
  128.         (-f0.0) jmpi (1)        Before_First_MB
  129.    END_THREAD
  130.  
  131. // Check whether it is before the first MB
  132. Before_First_MB:
  133.         cmp.e.f0.0 (1)  NULLREG AVAILFLAGD<1>:ud        0x08020401:ud   // in ACBD order
  134.         (f0.0) jmpi (1) Wavefront_Walk
  135.  
  136. Scoreboard_State_Init:
  137. #endif  // End AS_ENABLED
  138.         mov (2) WFLen_B<2>:w            HEIGHTINMB_1<0;1,0>:w
  139.         mov (1) AVAILFLAGD<1>:ud        0x08020401:ud   // in ACBD order
  140.         mov     (1) CASE00PTR<1>:ud     Notify_MSG_IP-No_Message_IP:ud          // Inter kernel starts
  141.         mov     (1) CASE10PTR<1>:ud     Dependency_Check_IP-No_Message_IP:ud    // Intra kernel starts
  142. #ifdef  AS_ENABLED
  143.         mov     (1) CASE11PTR<1>:ud     0:ud            // No message
  144. #else
  145.         mov     (1) CASE11PTR<1>:ud     MB_Loop_IP-No_Message_IP:ud             // No message
  146. #endif  // End AS_ENABLED
  147.         mov     (1) StartXD<1>:ud       0:ud
  148.         mov     (1) NewWFOffsetD<1>:ud  0x01ffff00:ud
  149.  
  150.         mov (4) WFStart(0)<1>   0xffff:w
  151.         mov (1) WFStart(0)<1>   0:w
  152.  
  153.         mov     (8)     a0.0<1>:uw      0x0:uw                                          // Initialize all pointers to 0
  154.  
  155. //------------------------------------------------------------------------
  156. //      Scoreboard message handling loop
  157. //------------------------------------------------------------------------
  158. //
  159. Scoreboard_Loop:
  160.         // Calculate current wavefront length
  161.         add.ge.f0.1 (16)        acc0<1>:w       StartX<0;1,0>:w 0:w             // Used for x>2*y check
  162.         mac.g.f0.0 (16) NULLREGW        WFLenY<0;1,0>:w -2:w            // X - 2*Y > 0 ??
  163.         (f0.0) mov (1)  WFLen<1>:w      WFLenY<0;1,0>:w                         // Use smaller vertical wavefront length
  164.         (-f0.0) asr.sat (1)     WFLen<1>:uw     StartX<0;1,0>:w 1:w             // Horizontal wavefront length is smaller
  165.  
  166.         // Initialize 5-MB group
  167. #ifdef ONE_MB_WA
  168.         mov (2) MBINDEX(0)<1>           WFStart(0)<2;2,1>
  169.         (f0.1) add (4) MBINDEX(0,2)<1>          WFStart(0,1)<4;4,1>     -1:w
  170.         (-f0.1) add (4) MBINDEX(0,2)<1>         WFStart(0,0)<4;4,1>     -1:w
  171.         (-f0.1) mov (1) StartX<1>:w             0:w                                     // WA for 1-MB wide pictures
  172. #else
  173.         mov (2) MBINDEX(0)<1>           WFStart(0)<2;2,1>                       {NoDDClr}
  174.         add (4) MBINDEX(0,2)<1>         WFStart(0,1)<4;4,1>     -1:w    {NoDDChk}
  175. #endif
  176.  
  177.         // Update WFStart
  178.         mov (8) acc0<1>:w       WFStart(0)<0;1,0>                                       // Move WFStart(0) to acc0 to remove dependency later
  179.         mov (4) WFStart(0,1)<1> WFStart(0)<4;4,1>       {NoDDClr}       // Shift WFStart(0:2) to WFStart(1:3)
  180.         add (1) WFStart(0)<1>   acc0.0<0;1,0>:w         WFLen<0;1,0>:w  {NoDDChk}       // WFStart(0) = WFStart(0) + WFLen
  181.  
  182.         mul (8) MBINDEX(0)<1>   MBINDEX(0)<8;8,1>       4:w     // Adjust MB order # to be DWORD aligned
  183.         and (1) DEPPTR<1>:uw    acc0<0;1,0>:w   SB_MASK*4:uw {NoDDClr}  // Wrap around scoreboard entries for current MB
  184.         and (4) DEPPTRL<1>:uw   acc0.1<4;4,1>:w SB_MASK*4:uw {NoDDChk}  // Wrap around scoreboard entries for neighbor MBs
  185.  
  186. Wavefront_Walk:
  187.         wait    n0:ud
  188. //      Check for combined "checking" or "completed" threads in forwarded message
  189. //      2 MSB of scoreboard message indicate:
  190. //      0b00 = "inter start" message
  191. //      0b10 = "intra start" message
  192. //      0b11 = "No Message" or "inter complete" message
  193. //      0b01 = Reserved (should never occur)
  194. //
  195. MB_Loop:
  196.         shr     (1)     PMSGSEL<1>:uw   r[CMDPTR,CMD_SB_REG_OFF*GRFWIB+2]<0;1,0>:uw     12:w                                    // DWORD aligned pointer to message handler
  197.         and.nz.f0.1 (4) NULLREG r[CMDPTR,CMD_SB_REG_OFF*GRFWIB]<0;1,0>:ub       AVAILFLAG<4;4,1>:ub             // f0.1 4 LSB will have the available flags in ACBD order
  198.         mov (1) MSGHDRY0.4<1>:ud        r[CMDPTR,CMD_SB_REG_OFF*GRFWIB]<0;1,0>:ud               // Copy MB thread info from scoreboard
  199.         jmpi (1)        r[PMSGSEL, INLINE_REG_OFF*GRFWIB+16]<0;1,0>:d
  200.  
  201. //      Now determine whether this is "inter done" or "no message"
  202. //      through checking debug_counter
  203. //
  204. No_Message:
  205. #ifdef  AS_ENABLED
  206.         cmp.z.f0.1 (1)  NULLREG n0:ud   0       // Are all messages handled?
  207.         and.z.f0.0 (1)  NULLREG cr0.1:ud        AS_INT  // Poll interrupt bit
  208.         (-f0.1) jmpi (1)        MB_Loop                 // Continue polling the remaining message from current thread
  209.  
  210. // All messages have been handled
  211.         (f0.0) jmpi (1) Wavefront_Walk          // No interrupt occurs. Wait for next one
  212.  
  213. // Interrupt has been detected
  214. // Save all contents and terminate the scoreboard
  215. //
  216.         #include "scoreboard_save_AS.asm"
  217.  
  218.         // Save scoreboard control data as well
  219.         //
  220.         mov (8) AR_SAVE<1>:uw   a0.0<8;8,1>:uw          // All address registers needs to be saved
  221.     mov (1)     MSGHDR.1:ud             64:ud
  222.     mov (1)     MSGHDR.2:ud             0x0002001f:ud   // for 3 registers
  223.         $for(0; <3; 1) {
  224.         mov (8) MSGPAYLOADD(%1)<1>      CMD_SB(%1-3)REGION(8,1)
  225.         }
  226.     send (8)    NULLREG MSGHDR  null:ud DWBWMSGDSC+0x00300000+AS_SAVE   // Save r1 - r3
  227.  
  228.         send (8) NULLREG MSGHDR r0:ud EOTMSGDSC+TH_INT  // Terminate with "Thread Interrupted" bit set
  229. #endif  // End AS_ENABLED
  230.  
  231. Dependency_Check:
  232. //      Current thread is "checking" but not "completed" (0b10 case).
  233. //      Check for dependency clear using all availability bits
  234. //
  235.         (f0.1) and.z.f0.1 (4)   NULLREG r[DEPPTRL,CMD_SB_REG_OFF*GRFWIB+3]<1,0>:ub      DONEFLAG:uw     // f0.1 4 LSB contains dependency clear
  236.         (f0.1.any4h) jmpi (1)   Dependency_Check                // Dependency not clear, keep polling..
  237.  
  238. //      "Checking" thread and dependency cleared, send a message to let the thread go
  239. //
  240. Notify_MSG:
  241.         send (8)        NULLREG  MSGHDRY0       null:ud    MSG_GW       FWDMSGDSC+NOTIFYMSG
  242.  
  243. //      Current macroblock has been serviced. Update to next macroblock in special zig-zag order
  244. //
  245. Update_CurMB:
  246. #if 0
  247.         add.ge.f0.0 (1) WFLen<1>:w      WFLen<0;1,0>:w  -1:w                    // Set "End of wavefront" flag
  248.         add (1) TotalMB<1>:w    TotalMB<0;1,0>:w        -1:w                    // Decrement "TotalMB"
  249. #else
  250.         add.ge.f0.0 (2) TotalMB<2>:w    TotalMB<4;2,2>:w        -1:w    // Set "End of wavefront" flag and decrement "TotalMB"
  251. #endif
  252.         add (8) MBINDEX(0)<1>   MBINDEX(0)<8;8,1>       4:w                             // Increment MB indices
  253.         and (1) DEPPTR<1>:uw    acc0<0;1,0>:w   SB_MASK*4:uw {NoDDClr}  // Wrap around 256 scoreboard entries for current MB
  254.         and (4) DEPPTRL<1>:uw   acc0.1<4;4,1>:w SB_MASK*4:uw {NoDDChk}  // Wrap around 256 scoreboard entries for neighbor MBs
  255.         cmp.e.f0.1 (16) NULLREGW  StartX<0;1,0>:uw      WIDTHINMB_1<0;1,0>:uw   // Set "on picture right boundary" flag
  256. #if 0
  257.         (f0.0) jmpi (1) Wavefront_Walk                  // Continue wavefront walking
  258. #else
  259.         (f0.0.all2h) jmpi (1) Wavefront_Walk    // Continue wavefront walking
  260. #endif
  261.  
  262. //      Start new wavefront
  263. //
  264.         cmp.e.f0.0 (1)  NULLREG TotalMB<0;1,0>:w                0:w     // Set "Last MB" flag
  265.         (f0.1) add (4)  WFLen<1>:w      WFLen<4;4,1>:w          NewWFOffset<4;4,1>:b
  266.         (f0.1) add (4)  WFStart(0)<1>   WFStart(0)<4;4,1>       1:w
  267.         (-f0.1) add (1) StartX<1>:w             StartX<0;1,0>:w 1:w             // Move to right MB
  268.         (-f0.1) add (1) WFStart(0)<1>   WFStart(0)<0;1,0>       1:w
  269.  
  270.         (-f0.0) jmpi (1)        Scoreboard_Loop                         // Not last MB, start new wavefront walking
  271.  
  272. // All MBs have decoded. Terminate the thread now
  273. //
  274.    END_THREAD
  275.  
  276. #if !defined(COMBINED_KERNEL)           // For standalone kernel only
  277. .end_code
  278.  
  279. .end_kernel
  280. #endif
  281.  
  282. // End of scoreboard
  283.