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.  * Permission is hereby granted, free of charge, to any person obtaining a
  6.  * copy of this software and associated documentation files (the
  7.  * "Software"), to deal in the Software without restriction, including
  8.  * without limitation the rights to use, copy, modify, merge, publish,
  9.  * distribute, sub license, and/or sell copies of the Software, and to
  10.  * permit persons to whom the Software is furnished to do so, subject to
  11.  * the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice (including the
  14.  * next paragraph) shall be included in all copies or substantial portions
  15.  * of the Software.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  18.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  19.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  20.  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
  21.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  22.  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  23.  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  24.  *
  25.  * This file was originally licensed under the following license
  26.  *
  27.  *  Licensed under the Apache License, Version 2.0 (the "License");
  28.  *  you may not use this file except in compliance with the License.
  29.  *  You may obtain a copy of the License at
  30.  *
  31.  *      http://www.apache.org/licenses/LICENSE-2.0
  32.  *
  33.  *  Unless required by applicable law or agreed to in writing, software
  34.  *  distributed under the License is distributed on an "AS IS" BASIS,
  35.  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  36.  *  See the License for the specific language governing permissions and
  37.  *  limitations under the License.
  38.  *
  39.  */
  40. // Kernel name: scoreboard.asm
  41. //
  42. // Dependency control scoreboard kernel
  43. //
  44. //  $Revision: 16 $
  45. //  $Date: 10/18/06 4:10p $
  46. //
  47.  
  48. // ----------------------------------------------------
  49. //  Main: scoreboard
  50. // ----------------------------------------------------
  51. // ----------------------------------------------------
  52. //  Scoreboard structure
  53. // ----------------------------------------------------
  54. //
  55. //      1 DWORD per thread
  56. //
  57. //      Bit 31: "Checking" thread, i.e. an intra MB that sends "check dependency" message
  58. //      Bit 30: "Completed" thread. This bit set by an "update" message from intra/inter MB.
  59. //      Bits 29:28:     Must set to 0
  60. //      Bits 27:24:     EUID
  61. //      Bits 23:18: Reserved
  62. //      Bits 17:16: TID
  63. //      Bits 15:8:      X offset of current MB
  64. //      Bits 15:5:      Reserved
  65. //      Bits 4:0: 5 bits of available neighbor MB flags
  66.  
  67. .kernel scoreboard
  68. SCOREBOARD:
  69.  
  70. #ifdef _DEBUG
  71. // WA for FULSIM so we'll know which kernel is being debugged
  72. mov (1) acc0:ud 0xf0aa55a5:ud
  73. #endif
  74.  
  75. #include "header.inc"
  76. #include "scoreboard_header.inc"
  77.  
  78. //
  79. //  Now, begin source code....
  80. //
  81.  
  82. .code
  83.  
  84. #ifdef  AS_ENABLED
  85.         and.z.f0.1      (1)     NULLREG r0.2<0;1,0>:ud  TH_RES  // Is this a restarted thread previously interrupted?
  86.         (f0.1) jmpi     (1)     Scoreboard_Init
  87.  
  88.         #include "scoreboard_restore_AS.asm"
  89.  
  90.         jmpi (1)        Scoreboard_OpenGW
  91. Scoreboard_Init:
  92. #endif  // End AS_ENABLED
  93.  
  94. // Scoreboard must be initialized to 0xc000ffff, meaning all "completed"
  95. // And it also avoids message mis-handling for the first MB
  96.    $for(0; <32; 2) {
  97.         mov (16)        CMD_SB(%1)<1>   0xc000ffff:ud {Compr}
  98.         }
  99. #ifdef  DOUBLE_SB                                       // Scoreboard size needs to be doubled
  100.    $for(32; <64; 2) {
  101.         mov (16)        CMD_SB(%1)<1>   0xc000ffff:ud {Compr}
  102.         }
  103. #endif  // DOUBLE_SB
  104.  
  105. //----------------------------------------------------------
  106. //      Open message gateway for the scoreboard thread
  107. //
  108. //      RegBase = r4 (0x04)
  109. //      Gateway Size = 64 GRF registers (0x6)
  110. //      Dispatch ID = r0.20:ub
  111. //      Scoreboard Thread Key = 0
  112. //----------------------------------------------------------
  113. Scoreboard_OpenGW:
  114.     mov (8)     MSGHDRY0<1>:ud  0x00000000:ud                   // Initialize message header payload with 0
  115.  
  116.         // Send a message with register base RegBase=0x04(r4) and Gateway size = 0x6 = 64 GRF reg and Key = 0
  117.         // 000 00000100 00000 00000 110 00000000 ==> 0000 0000 1000 0000 0000 0110 0000 0000
  118. #ifdef  AS_ENABLED
  119.         add (1) MSGHDRY0.5<1>:ud r0.20:ub       0x00800700:ud   // Allocate 128 GRFs for message gateway - for SIP to send notification MSG
  120. #else
  121.   #ifdef        DOUBLE_SB
  122.         add (1) MSGHDRY0.5<1>:ud r0.20:ub       0x00800600:ud   // 64 GRF's for CTG-B
  123.   #else
  124.         add (1) MSGHDRY0.5<1>:ud r0.20:ub       0x00800500:ud   // 32 GRF's for CTG-A
  125.   #endif        // DOUBLE_SB
  126. #endif
  127.         send (8)        NULLREG  MSGHDRY0       null:ud    MSG_GW       OGWMSGDSC
  128.  
  129. //------------------------------------------------------------------------
  130. //      Send Thread Spawning Message to start dispatching macroblock threads
  131. //
  132. //------------------------------------------------------------------------
  133. #ifdef  AS_ENABLED
  134.         mov (8) acc0<1>:ud      CMD_SB(31)<8;8,1>                       // Ensure scoreboard data have been completely restored
  135. #endif  // End AS_ENABLED
  136.     mov (8)     MSGHDRY1<1>:ud          r0<8;8,1>:ud            // Initialize message header payload with R0
  137.     mov (1)     MSGHDRY1.4<1>:ud        0x00000400:ud           // Dispatch URB length = 1
  138.  
  139.         send (8)        NULLREG  MSGHDRY1       null:ud    TS   TSMSGDSC
  140.  
  141.     mov (8)     MSGHDRY0<1>:ud          0x00000000:ud           // Initialize message header payload with 0
  142.  
  143. //------------------------------------------------------------------------
  144. //      Scoreboard control data initialization
  145. //------------------------------------------------------------------------
  146. #ifdef  AS_ENABLED
  147.         or      (1)     cr0.1:ud        cr0.1:ud        AS_INT_EN               // Enable interrupt
  148.         (f0.1) jmpi     (1)     Scoreboard_State_Init   // Jump if not restarted thread
  149.  
  150.         // Restore scoreboard kernel control data to r1 - r3
  151.     mov (1)     m4.1:ud 64:ud                           // Starting r1
  152.     mov (1)     m4.2:ud 0x0002001f:ud           // for 3 registers
  153.     send (8)    r1.0<1>:ud      m4      null:ud DWBRMSGDSC_SC+0x00030000+AS_SAVE        // Restore r1 - r3
  154.         mov     (8)     a0.0<1>:uw      AR_SAVE<8;8,1>:uw                               // Restore all address registers
  155.  
  156. // Check whether all MBs have been decoded
  157.         cmp.e.f0.0 (1)  NULLREG TotalMB<0;1,0>:w        0:w     // Set "Last MB" flag
  158.         (-f0.0) jmpi (1)        Before_First_MB
  159.    END_THREAD
  160.  
  161. // Check whether it is before the first MB
  162. Before_First_MB:
  163.         cmp.e.f0.0 (1)  NULLREG AVAILFLAGD<1>:ud        0x08020401:ud   // in ACBD order
  164.         (f0.0) jmpi (1) Wavefront_Walk
  165.  
  166. Scoreboard_State_Init:
  167. #endif  // End AS_ENABLED
  168.         mov (2) WFLen_B<2>:w            HEIGHTINMB_1<0;1,0>:w
  169.         mov (1) AVAILFLAGD<1>:ud        0x08020401:ud   // in ACBD order
  170.         mov     (1) CASE00PTR<1>:ud     Notify_MSG_IP-No_Message_IP:ud          // Inter kernel starts
  171.         mov     (1) CASE10PTR<1>:ud     Dependency_Check_IP-No_Message_IP:ud    // Intra kernel starts
  172. #ifdef  AS_ENABLED
  173.         mov     (1) CASE11PTR<1>:ud     0:ud            // No message
  174. #else
  175.         mov     (1) CASE11PTR<1>:ud     MB_Loop_IP-No_Message_IP:ud             // No message
  176. #endif  // End AS_ENABLED
  177.         mov     (1) StartXD<1>:ud       0:ud
  178.         mov     (1) NewWFOffsetD<1>:ud  0x01ffff00:ud
  179.  
  180.         mov (4) WFStart(0)<1>   0xffff:w
  181.         mov (1) WFStart(0)<1>   0:w
  182.  
  183.         mov     (8)     a0.0<1>:uw      0x0:uw                                          // Initialize all pointers to 0
  184.  
  185. //------------------------------------------------------------------------
  186. //      Scoreboard message handling loop
  187. //------------------------------------------------------------------------
  188. //
  189. Scoreboard_Loop:
  190.         // Calculate current wavefront length
  191.         add.ge.f0.1 (16)        acc0<1>:w       StartX<0;1,0>:w 0:w             // Used for x>2*y check
  192.         mac.g.f0.0 (16) NULLREGW        WFLenY<0;1,0>:w -2:w            // X - 2*Y > 0 ??
  193.         (f0.0) mov (1)  WFLen<1>:w      WFLenY<0;1,0>:w                         // Use smaller vertical wavefront length
  194.         (-f0.0) asr.sat (1)     WFLen<1>:uw     StartX<0;1,0>:w 1:w             // Horizontal wavefront length is smaller
  195.  
  196.         // Initialize 5-MB group
  197. #ifdef ONE_MB_WA
  198.         mov (2) MBINDEX(0)<1>           WFStart(0)<2;2,1>
  199.         (f0.1) add (4) MBINDEX(0,2)<1>          WFStart(0,1)<4;4,1>     -1:w
  200.         (-f0.1) add (4) MBINDEX(0,2)<1>         WFStart(0,0)<4;4,1>     -1:w
  201.         (-f0.1) mov (1) StartX<1>:w             0:w                                     // WA for 1-MB wide pictures
  202. #else
  203.         mov (2) MBINDEX(0)<1>           WFStart(0)<2;2,1>                       {NoDDClr}
  204.         add (4) MBINDEX(0,2)<1>         WFStart(0,1)<4;4,1>     -1:w    {NoDDChk}
  205. #endif
  206.  
  207.         // Update WFStart
  208.         mov (8) acc0<1>:w       WFStart(0)<0;1,0>                                       // Move WFStart(0) to acc0 to remove dependency later
  209.         mov (4) WFStart(0,1)<1> WFStart(0)<4;4,1>       {NoDDClr}       // Shift WFStart(0:2) to WFStart(1:3)
  210.         add (1) WFStart(0)<1>   acc0.0<0;1,0>:w         WFLen<0;1,0>:w  {NoDDChk}       // WFStart(0) = WFStart(0) + WFLen
  211.  
  212.         mul (8) MBINDEX(0)<1>   MBINDEX(0)<8;8,1>       4:w     // Adjust MB order # to be DWORD aligned
  213.         and (1) DEPPTR<1>:uw    acc0<0;1,0>:w   SB_MASK*4:uw {NoDDClr}  // Wrap around scoreboard entries for current MB
  214.         and (4) DEPPTRL<1>:uw   acc0.1<4;4,1>:w SB_MASK*4:uw {NoDDChk}  // Wrap around scoreboard entries for neighbor MBs
  215.  
  216. Wavefront_Walk:
  217.         wait    n0:ud
  218. //      Check for combined "checking" or "completed" threads in forwarded message
  219. //      2 MSB of scoreboard message indicate:
  220. //      0b00 = "inter start" message
  221. //      0b10 = "intra start" message
  222. //      0b11 = "No Message" or "inter complete" message
  223. //      0b01 = Reserved (should never occur)
  224. //
  225. MB_Loop:
  226.         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
  227.         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
  228.         mov (1) MSGHDRY0.4<1>:ud        r[CMDPTR,CMD_SB_REG_OFF*GRFWIB]<0;1,0>:ud               // Copy MB thread info from scoreboard
  229.         jmpi (1)        r[PMSGSEL, INLINE_REG_OFF*GRFWIB+16]<0;1,0>:d
  230.  
  231. //      Now determine whether this is "inter done" or "no message"
  232. //      through checking debug_counter
  233. //
  234. No_Message:
  235. #ifdef  AS_ENABLED
  236.         cmp.z.f0.1 (1)  NULLREG n0:ud   0       // Are all messages handled?
  237.         and.z.f0.0 (1)  NULLREG cr0.1:ud        AS_INT  // Poll interrupt bit
  238.         (-f0.1) jmpi (1)        MB_Loop                 // Continue polling the remaining message from current thread
  239.  
  240. // All messages have been handled
  241.         (f0.0) jmpi (1) Wavefront_Walk          // No interrupt occurs. Wait for next one
  242.  
  243. // Interrupt has been detected
  244. // Save all contents and terminate the scoreboard
  245. //
  246.         #include "scoreboard_save_AS.asm"
  247.  
  248.         // Save scoreboard control data as well
  249.         //
  250.         mov (8) AR_SAVE<1>:uw   a0.0<8;8,1>:uw          // All address registers needs to be saved
  251.     mov (1)     MSGHDR.1:ud             64:ud
  252.     mov (1)     MSGHDR.2:ud             0x0002001f:ud   // for 3 registers
  253.         $for(0; <3; 1) {
  254.         mov (8) MSGPAYLOADD(%1)<1>      CMD_SB(%1-3)REGION(8,1)
  255.         }
  256.     send (8)    NULLREG MSGHDR  null:ud DWBWMSGDSC+0x00300000+AS_SAVE   // Save r1 - r3
  257.  
  258.         send (8) NULLREG MSGHDR r0:ud EOTMSGDSC+TH_INT  // Terminate with "Thread Interrupted" bit set
  259. #endif  // End AS_ENABLED
  260.  
  261. Dependency_Check:
  262. //      Current thread is "checking" but not "completed" (0b10 case).
  263. //      Check for dependency clear using all availability bits
  264. //
  265.         (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
  266.         (f0.1.any4h) jmpi (1)   Dependency_Check                // Dependency not clear, keep polling..
  267.  
  268. //      "Checking" thread and dependency cleared, send a message to let the thread go
  269. //
  270. Notify_MSG:
  271.         send (8)        NULLREG  MSGHDRY0       null:ud    MSG_GW       FWDMSGDSC+NOTIFYMSG
  272.  
  273. //      Current macroblock has been serviced. Update to next macroblock in special zig-zag order
  274. //
  275. Update_CurMB:
  276. #if 0
  277.         add.ge.f0.0 (1) WFLen<1>:w      WFLen<0;1,0>:w  -1:w                    // Set "End of wavefront" flag
  278.         add (1) TotalMB<1>:w    TotalMB<0;1,0>:w        -1:w                    // Decrement "TotalMB"
  279. #else
  280.         add.ge.f0.0 (2) TotalMB<2>:w    TotalMB<4;2,2>:w        -1:w    // Set "End of wavefront" flag and decrement "TotalMB"
  281. #endif
  282.         add (8) MBINDEX(0)<1>   MBINDEX(0)<8;8,1>       4:w                             // Increment MB indices
  283.         and (1) DEPPTR<1>:uw    acc0<0;1,0>:w   SB_MASK*4:uw {NoDDClr}  // Wrap around 256 scoreboard entries for current MB
  284.         and (4) DEPPTRL<1>:uw   acc0.1<4;4,1>:w SB_MASK*4:uw {NoDDChk}  // Wrap around 256 scoreboard entries for neighbor MBs
  285.         cmp.e.f0.1 (16) NULLREGW  StartX<0;1,0>:uw      WIDTHINMB_1<0;1,0>:uw   // Set "on picture right boundary" flag
  286. #if 0
  287.         (f0.0) jmpi (1) Wavefront_Walk                  // Continue wavefront walking
  288. #else
  289.         (f0.0.all2h) jmpi (1) Wavefront_Walk    // Continue wavefront walking
  290. #endif
  291.  
  292. //      Start new wavefront
  293. //
  294.         cmp.e.f0.0 (1)  NULLREG TotalMB<0;1,0>:w                0:w     // Set "Last MB" flag
  295.         (f0.1) add (4)  WFLen<1>:w      WFLen<4;4,1>:w          NewWFOffset<4;4,1>:b
  296.         (f0.1) add (4)  WFStart(0)<1>   WFStart(0)<4;4,1>       1:w
  297.         (-f0.1) add (1) StartX<1>:w             StartX<0;1,0>:w 1:w             // Move to right MB
  298.         (-f0.1) add (1) WFStart(0)<1>   WFStart(0)<0;1,0>       1:w
  299.  
  300.         (-f0.0) jmpi (1)        Scoreboard_Loop                         // Not last MB, start new wavefront walking
  301.  
  302. // All MBs have decoded. Terminate the thread now
  303. //
  304.    END_THREAD
  305.  
  306. #if !defined(COMBINED_KERNEL)           // For standalone kernel only
  307. .end_code
  308.  
  309. .end_kernel
  310. #endif
  311.  
  312. // End of scoreboard
  313.