nvc0: add MP trap handler for nve4
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>
Sat, 9 Mar 2013 16:17:14 +0000 (17:17 +0100)
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>
Tue, 12 Mar 2013 11:55:37 +0000 (12:55 +0100)
src/gallium/drivers/nvc0/codegen/target_lib_nve4.asm
src/gallium/drivers/nvc0/codegen/target_lib_nve4.asm.h
src/gallium/drivers/nvc0/nve4_compute.c
src/gallium/drivers/nvc0/nve4_compute.h

index 2ed8c0af8713c6b6a925d9e09c29c3a203476640..5adc9ff38a583a53fe498c4baa63e7b5604e8f11 100644 (file)
@@ -561,3 +561,138 @@ long ret
 //
 long nop
 long ret
+//
+// Trap handler.
+// Requires at least 4 GPRs and 32 bytes of l[] memory to temporarily save GPRs.
+// Low 32 bytes of l[] memory shouldn't be used if resumeability is required.
+//
+// Trap info:
+// 0x000: mutex
+// 0x004: PC
+// 0x008: trapstat
+// 0x00c: warperr
+// 0x010: tidx
+// 0x014: tidy
+// 0x018: tidz
+// 0x01c: ctaidx
+// 0x020: ctaidy
+// 0x024: ctaidz
+// 0x030: $r0q
+// 0x130: $flags
+// 0x140: s[]
+//
+st b128 wb l[0x00] $r0q
+// check state of the warp and continue if it didn't cause the trap
+long mov b32 $r1 $trapstat
+long mov b32 $r3 $warperr
+mov $r2 $flags mask 0xffff
+and b32 0 $c $r1 $r3
+e $c bra #end_cont
+// spill control flow stack to l[]
+long mov b32 $r3 16
+spill_cfstack:
+preret #end_exit
+sub b32 $r3 $c $r3 0x1
+lg $c bra #spill_cfstack
+// retrieve pointer to trap info
+mov b32 $r0 c0[0x1900]
+mov b32 $r1 c0[0x1904]
+// we only let a single faulting thread store its state
+mov b32 $r3 0x1
+exch b32 $r3 g[$r0d] $r3
+joinat #end_exit
+set $p0 0x1 eq u32 $r3 0x1
+join $p0 nop
+// store $c and $p registers
+st b32 wb g[$r0d+0x130] $r2
+// store $trapstat and $warperr
+long mov b32 $r2 $trapstat
+long mov b32 $r3 $warperr
+st b64 wb g[$r0d+0x8] $r2d
+// store registers
+st b128 wb g[$r0d+0x40] $r4q
+st b128 wb g[$r0d+0x50] $r8q
+st b128 wb g[$r0d+0x60] $r12q
+st b128 wb g[$r0d+0x70] $r16q
+st b128 wb g[$r0d+0x80] $r20q
+st b128 wb g[$r0d+0x90] $r24q
+st b128 wb g[$r0d+0xa0] $r28q
+st b128 wb g[$r0d+0xb0] $r32q
+st b128 wb g[$r0d+0xc0] $r36q
+st b128 wb g[$r0d+0xd0] $r40q
+st b128 wb g[$r0d+0xe0] $r44q
+st b128 wb g[$r0d+0xf0] $r48q
+st b128 wb g[$r0d+0x100] $r52q
+st b128 wb g[$r0d+0x110] $r56q
+st b128 wb g[$r0d+0x120] $r60q
+ld b64 $r2d cs l[0x0]
+st b64 wb g[$r0d+0x30] $r2d
+ld b64 $r2d cs l[0x8]
+st b64 wb g[$r0d+0x38] $r2d
+// store thread id
+long mov b32 $r2 $tidx
+long mov b32 $r3 $tidy
+st b64 wb g[$r0d+0x10] $r2d
+long mov b32 $r2 $tidz
+long mov b32 $r3 $ctaidx
+st b64 wb g[$r0d+0x18] $r2d
+long mov b32 $r2 $ctaidy
+long mov b32 $r3 $ctaidz
+st b64 wb g[$r0d+0x20] $r2d
+// store shared memory (in reverse order so $r0d is base again at the end)
+long mov b32 $r3 $smemsz
+sub b32 $r3 $c $r3 0x4
+s $c bra #shared_done
+add b32 $r0 $c $r0 $r3
+add b32 $r1 $r1 0x0 $c
+shared_loop:
+long ld b32 $r2 s[$r3]
+long st b32 wb g[$r0d+0x140] $r2
+sub b32 $r0 $c $r0 0x4
+sub b32 $r1 $r1 0x0 $c
+sub b32 $r3 $c $r3 0x4
+lg $c bra #shared_loop
+shared_done:
+// search the stack for trap entry to retrieve PC
+mov b32 $r0 c0[0x1908]
+mov b32 $r1 c0[0x190c]
+membar sys
+// invalidate caches so we can read stack entries via g[]
+cctl ivall 0 l[0]
+cctl ivall 0 g[$r0d]
+// get offsets
+mov b32 $r2 $physid
+ext u32 $r3 $r2 0x0814 // MP id
+ext u32 $r2 $r2 0x0608 // warp id
+mul $r2 u32 $r2 u32 c0[0x1914] // warp offset
+mul $r3 u32 $r3 u32 c0[0x1910] // MP offset
+add b32 $r2 $r2 $r3 // MP + warp offset
+add b32 $r0 $c $r0 $r2
+add b32 $r1 $r1 0x0 $c
+search_cstack:
+mov b32 $r3 c0[0x1918] // cstack size
+ld u8 $r2 cv g[$r0d+0x8]
+set $p0 0x1 eq u32 $r2 0xa
+$p0 bra #entry_found
+add b32 $r0 $c $r0 0x10
+add b32 $r1 $r1 0x0 $c
+sub b32 $r3 $c $r3 0x10
+lg $c bra #search_cstack
+bra #end_exit
+entry_found:
+// load PC (may be unaligned and spread out)
+ld b32 $r2 cv g[$r0d]
+mov b32 $r0 c0[0x1900]
+mov b32 $r1 c0[0x1904]
+st b32 wb g[$r0d+0x4] $r2
+join nop
+// invalidate caches and exit
+end_exit:
+cctl ivall 0 g[0]
+bpt pause 0x0
+rtt terminate
+end_cont:
+bpt pause 0x0
+mov $flags $r2 mask 0xffff
+ld b128 $r0q cs l[0x00]
+rtt
index 526e75989d59587ee46cf54da0c2e10b127a1eee..ad386f8771a7ef72f0cb353357c749f5efc82aae 100644 (file)
@@ -488,6 +488,99 @@ static const uint64_t nve4_builtin_code[] =
    0x9000000000001de7ULL,
    0x4000000000001de4ULL,
    0x9000000000001de7ULL,
+   0xc800000003f01cc5ULL,
+   0x2c00000100005c04ULL,
+   0x2c0000010800dc04ULL,
+   0x3000c3fffff09c04ULL,
+   0x680100000c1fdc03ULL,
+   0x4000000a60001c47ULL,
+   0x180000004000dde2ULL,
+   0x78000009c0000007ULL,
+   0x0c0000000430dd02ULL,
+   0x4003ffffa0001ca7ULL,
+   0x2800406400001de4ULL,
+   0x2800406410005de4ULL,
+   0x180000000400dde2ULL,
+   0x547e18000000dd05ULL,
+   0x60000008e0000007ULL,
+   0x190ec0000431dc03ULL,
+   0x40000000000001f4ULL,
+   0x94000004c0009c85ULL,
+   0x2c00000100009c04ULL,
+   0x2c0000010800dc04ULL,
+   0x9400000020009ca5ULL,
+   0x9400000100011cc5ULL,
+   0x9400000140021cc5ULL,
+   0x9400000180031cc5ULL,
+   0x94000001c0041cc5ULL,
+   0x9400000200051cc5ULL,
+   0x9400000240061cc5ULL,
+   0x9400000280071cc5ULL,
+   0x94000002c0081cc5ULL,
+   0x9400000300091cc5ULL,
+   0x94000003400a1cc5ULL,
+   0x94000003800b1cc5ULL,
+   0x94000003c00c1cc5ULL,
+   0x94000004000d1cc5ULL,
+   0x94000004400e1cc5ULL,
+   0x94000004800f1cc5ULL,
+   0xc000000003f09ea5ULL,
+   0x94000000c0009ca5ULL,
+   0xc000000023f09ea5ULL,
+   0x94000000e0009ca5ULL,
+   0x2c00000084009c04ULL,
+   0x2c0000008800dc04ULL,
+   0x9400000040009ca5ULL,
+   0x2c0000008c009c04ULL,
+   0x2c0000009400dc04ULL,
+   0x9400000060009ca5ULL,
+   0x2c00000098009c04ULL,
+   0x2c0000009c00dc04ULL,
+   0x9400000080009ca5ULL,
+   0x2c000000c800dc04ULL,
+   0x0c0000001030dd02ULL,
+   0x4000000100001ea7ULL,
+   0x480100000c001c03ULL,
+   0x0800000000105c42ULL,
+   0xc100000000309c85ULL,
+   0x9400000500009c85ULL,
+   0x0c00000010001d02ULL,
+   0x0800000000105d42ULL,
+   0x0c0000001030dd02ULL,
+   0x4003ffff40001ca7ULL,
+   0x2800406420001de4ULL,
+   0x2800406430005de4ULL,
+   0xe000000000001c45ULL,
+   0xd000000003ffdcc5ULL,
+   0x9c000000000fdcc5ULL,
+   0x2c0000000c009c04ULL,
+   0x7000c0205020dc03ULL,
+   0x7000c01820209c03ULL,
+   0x5000406450209c03ULL,
+   0x500040644030dc03ULL,
+   0x480000000c209c03ULL,
+   0x4801000008001c03ULL,
+   0x0800000000105c42ULL,
+   0x280040646000dde4ULL,
+   0x8400000020009f05ULL,
+   0x190ec0002821dc03ULL,
+   0x40000000800001e7ULL,
+   0x0c00000040001c02ULL,
+   0x0800000000105c42ULL,
+   0x0c0000004030dd02ULL,
+   0x00029dff0ffc5cbfULL,
+   0x8400000000009f85ULL,
+   0x2800406400001de4ULL,
+   0x2800406410005de4ULL,
+   0x9400000010009c85ULL,
+   0x4000000000001df4ULL,
+   0x9800000003ffdcc5ULL,
+   0xd000000000008007ULL,
+   0xa000000000004007ULL,
+   0xd000000000008007ULL,
+   0x3400c3fffc201c04ULL,
+   0xc000000003f01ec5ULL,
+   0xa000000000000007ULL
 };
 
 static const uint16_t nve4_builtin_offsets[NVC0_BUILTIN_COUNT] =
index b5344e4eed6a9d6e6dfbb1458b4fb2f3b553d334..c61d90cf0d11ecb6208ef67ade2a1b532bc7a22a 100644 (file)
@@ -151,6 +151,25 @@ nve4_screen_compute_setup(struct nvc0_screen *screen,
    PUSH_DATA (push, 1);
    PUSH_DATA (push, 3); /* 7 */
    PUSH_DATA (push, 1);
+
+#ifdef DEBUG
+   BEGIN_NVC0(push, NVE4_COMPUTE(UPLOAD_ADDRESS_HIGH), 2);
+   PUSH_DATAh(push, screen->parm->offset + NVE4_CP_INPUT_TRAP_INFO_PTR);
+   PUSH_DATA (push, screen->parm->offset + NVE4_CP_INPUT_TRAP_INFO_PTR);
+   BEGIN_NVC0(push, NVE4_COMPUTE(UPLOAD_SIZE), 2);
+   PUSH_DATA (push, 28);
+   PUSH_DATA (push, NVE4_COMPUTE_UPLOAD_UNK0184_UNKVAL);
+   BEGIN_1IC0(push, NVE4_COMPUTE(UPLOAD_EXEC), 8);
+   PUSH_DATA (push, NVE4_COMPUTE_UPLOAD_EXEC_UNKVAL_DATA);
+   PUSH_DATA (push, screen->parm->offset + NVE4_CP_PARAM_TRAP_INFO);
+   PUSH_DATAh(push, screen->parm->offset + NVE4_CP_PARAM_TRAP_INFO);
+   PUSH_DATA (push, screen->tls->offset);
+   PUSH_DATAh(push, screen->tls->offset);
+   PUSH_DATA (push, screen->tls->size / 2); /* MP TEMP block size */
+   PUSH_DATA (push, screen->tls->size / 2 / 64); /* warp TEMP block size */
+   PUSH_DATA (push, 0); /* warp cfstack size */
+#endif
+
    BEGIN_NVC0(push, NVE4_COMPUTE(FLUSH), 1);
    PUSH_DATA (push, NVE4_COMPUTE_FLUSH_CB);
 
@@ -617,3 +636,34 @@ nve4_compute_dump_launch_desc(const struct nve4_cp_launch_desc *desc)
    }
 }
 
+static void
+nve4_compute_trap_info(struct nvc0_context *nvc0)
+{
+   struct nvc0_screen *screen = nvc0->screen;
+   struct nouveau_bo *bo = screen->parm;
+   int ret, i;
+   volatile struct nve4_mp_trap_info *info;
+   uint8_t *map;
+
+   ret = nouveau_bo_map(bo, NOUVEAU_BO_RDWR, nvc0->base.client);
+   if (ret)
+      return;
+   map = (uint8_t *)bo->map;
+   info = (volatile struct nve4_mp_trap_info *)(map + NVE4_CP_PARAM_TRAP_INFO);
+
+   if (info->lock) {
+      debug_printf("trapstat = %08x\n", info->trapstat);
+      debug_printf("warperr = %08x\n", info->warperr);
+      debug_printf("PC = %x\n", info->pc);
+      debug_printf("tid = %u %u %u\n",
+                   info->tid[0], info->tid[1], info->tid[2]);
+      debug_printf("ctaid = %u %u %u\n",
+                   info->ctaid[0], info->ctaid[1], info->ctaid[2]);
+      for (i = 0; i <= 63; ++i)
+         debug_printf("$r%i = %08x\n", i, info->r[i]);
+      for (i = 0; i <= 6; ++i)
+         debug_printf("$p%i = %i\n", i, (info->flags >> i) & 1);
+      debug_printf("$c = %x\n", info->flags >> 12);
+   }
+   info->lock = 0;
+}
index 11d89283cc04b628497d189c1471bb6c952020b8..91d64fff695130ca955b8c9e73b5eb5285df055b 100644 (file)
@@ -7,21 +7,28 @@
 
 /* Input space is implemented as c0[], to which we bind the screen->parm bo.
  */
-#define NVE4_CP_INPUT_USER          0x0000
-#define NVE4_CP_INPUT_USER_LIMIT    0x1000
-#define NVE4_CP_INPUT_GRID_INFO(i) (0x1000 + (i) * 4)
-#define NVE4_CP_INPUT_NTID(i)      (0x1000 + (i) * 4)
-#define NVE4_CP_INPUT_NCTAID(i)    (0x100c + (i) * 4)
-#define NVE4_CP_INPUT_GRIDID        0x1018
-#define NVE4_CP_INPUT_TEX(i)       (0x1040 + (i) * 4)
-#define NVE4_CP_INPUT_TEX_STRIDE    4
-#define NVE4_CP_INPUT_TEX_MAX       32
-#define NVE4_CP_INPUT_MS_OFFSETS    0x10c0
-#define NVE4_CP_INPUT_SUF_STRIDE    64
-#define NVE4_CP_INPUT_SUF(i)       (0x1100 + (i) * NVE4_CP_INPUT_SUF_STRIDE)
-#define NVE4_CP_INPUT_SUF_MAX       32
-#define NVE4_CP_INPUT_SIZE          0x1900
-#define NVE4_CP_PARAM_SIZE          0x2000
+#define NVE4_CP_INPUT_USER           0x0000
+#define NVE4_CP_INPUT_USER_LIMIT     0x1000
+#define NVE4_CP_INPUT_GRID_INFO(i)  (0x1000 + (i) * 4)
+#define NVE4_CP_INPUT_NTID(i)       (0x1000 + (i) * 4)
+#define NVE4_CP_INPUT_NCTAID(i)     (0x100c + (i) * 4)
+#define NVE4_CP_INPUT_GRIDID         0x1018
+#define NVE4_CP_INPUT_TEX(i)        (0x1040 + (i) * 4)
+#define NVE4_CP_INPUT_TEX_STRIDE     4
+#define NVE4_CP_INPUT_TEX_MAX        32
+#define NVE4_CP_INPUT_MS_OFFSETS     0x10c0
+#define NVE4_CP_INPUT_SUF_STRIDE     64
+#define NVE4_CP_INPUT_SUF(i)        (0x1100 + (i) * NVE4_CP_INPUT_SUF_STRIDE)
+#define NVE4_CP_INPUT_SUF_MAX        32
+#define NVE4_CP_INPUT_TRAP_INFO_PTR  0x1900
+#define NVE4_CP_INPUT_TEMP_PTR       0x1908
+#define NVE4_CP_INPUT_MP_TEMP_SIZE   0x1910
+#define NVE4_CP_INPUT_WARP_TEMP_SIZE 0x1914
+#define NVE4_CP_INPUT_CSTACK_SIZE    0x1918
+#define NVE4_CP_INPUT_SIZE           0x1a00
+#define NVE4_CP_PARAM_TRAP_INFO      0x2000
+#define NVE4_CP_PARAM_TRAP_INFO_SZ  (1 << 16)
+#define NVE4_CP_PARAM_SIZE          (NVE4_CP_PARAM_TRAP_INFO + (1 << 16))
 
 struct nve4_cp_launch_desc
 {
@@ -111,4 +118,18 @@ nve4_cp_launch_desc_set_ctx_cb(struct nve4_cp_launch_desc *desc,
    }
 }
 
+struct nve4_mp_trap_info {
+   u32 lock;
+   u32 pc;
+   u32 trapstat;
+   u32 warperr;
+   u32 tid[3];
+   u32 ctaid[3];
+   u32 pad028[2];
+   u32 r[64];
+   u32 flags;
+   u32 pad134[3];
+   u32 s[0x3000];
+};
+
 #endif /* NVE4_COMPUTE_H */