From patchwork Tue Nov 26 16:51:31 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: bradley.d.volkin@intel.com X-Patchwork-Id: 3239681 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 1EDF1C045B for ; Tue, 26 Nov 2013 16:52:43 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id B619D203F3 for ; Tue, 26 Nov 2013 16:52:41 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 728DB20416 for ; Tue, 26 Nov 2013 16:52:39 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 009CFF9CDC; Tue, 26 Nov 2013 08:52:28 -0800 (PST) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by gabe.freedesktop.org (Postfix) with ESMTP id E53FEFB2F8 for ; Tue, 26 Nov 2013 08:52:24 -0800 (PST) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga102.jf.intel.com with ESMTP; 26 Nov 2013 08:48:46 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.93,775,1378882800"; d="scan'208";a="415344909" Received: from bdvolkin-desk1.amr.corp.intel.com (HELO localhost.localdomain) ([10.10.34.110]) by orsmga001.jf.intel.com with ESMTP; 26 Nov 2013 08:52:24 -0800 From: bradley.d.volkin@intel.com To: intel-gfx@lists.freedesktop.org Date: Tue, 26 Nov 2013 08:51:31 -0800 Message-Id: <1385484699-51596-15-git-send-email-bradley.d.volkin@intel.com> X-Mailer: git-send-email 1.8.4.4 In-Reply-To: <1385484699-51596-1-git-send-email-bradley.d.volkin@intel.com> References: <1385484699-51596-1-git-send-email-bradley.d.volkin@intel.com> Subject: [Intel-gfx] [RFC 14/22] drm/i915: Enable PPGTT command parser checks X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Brad Volkin Various commands that access memory have a bit to determine whether the graphics address specified in the command should use the GGTT or PPGTT for translation. These checks ensure that the bit indicates PPGTT translation. Most of these checks use the existing bit-checking infrastructure. The PIPE_CONTROL and MI_FLUSH_DW commands, however, are multi-function commands. The GGTT/PPGTT bit is only relevant for certain uses of the command. As such, this change also extends the bit-checking code to include a "condition" mask and offset. If the condition mask is non-zero then the parser only performs the bit check when the bits specified by the condition mask/offset are also non-zero. NOTE: At this point in the series PPGTT must be enabled for the parser to work correctly. If it's not enabled, userspace will not be setting the PPGTT bits the way the parser requires. There's a WARN_ON to detect this case. OTC-Tracker: AXIA-4631 Change-Id: I3f4c76b6734f1956ec47e698230f97d0998ff92b Signed-off-by: Brad Volkin --- drivers/gpu/drm/i915/i915_cmd_parser.c | 110 ++++++++++++++++++++++++++++++--- drivers/gpu/drm/i915/i915_drv.h | 6 ++ drivers/gpu/drm/i915/i915_reg.h | 5 ++ 3 files changed, 111 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c index b881d39..7b30a03 100644 --- a/drivers/gpu/drm/i915/i915_cmd_parser.c +++ b/drivers/gpu/drm/i915/i915_cmd_parser.c @@ -61,15 +61,33 @@ static const struct drm_i915_cmd_descriptor common_cmds[] = { CMD( MI_REPORT_HEAD, SMI, F, 1, S ), CMD( MI_SUSPEND_FLUSH, SMI, F, 1, S ), CMD( MI_SEMAPHORE_MBOX, SMI, !F, 0xFF, R ), - CMD( MI_STORE_DWORD_IMM, SMI, !F, 0x3FF, S ), + CMD( MI_STORE_DWORD_IMM, SMI, !F, 0x3FF, B, + .bits = {{ + .offset = 0, + .mask = MI_GLOBAL_GTT, + .expected = 0 + }}, + .bits_count = 1 ), CMD( MI_STORE_DWORD_INDEX, SMI, !F, 0xFF, R ), CMD( MI_LOAD_REGISTER_IMM(1), SMI, !F, 0xFF, W, .reg = { .offset = 1, .mask = 0x007FFFFC } ), CMD( MI_UPDATE_GTT, SMI, !F, 0xFF, R ), - CMD( MI_STORE_REGISTER_MEM(1), SMI, !F, 0xFF, W, - .reg = { .offset = 1, .mask = 0x007FFFFC } ), - CMD( MI_LOAD_REGISTER_MEM, SMI, !F, 0xFF, W, - .reg = { .offset = 1, .mask = 0x007FFFFC } ), + CMD( MI_STORE_REGISTER_MEM(1), SMI, !F, 0xFF, W | B, + .reg = { .offset = 1, .mask = 0x007FFFFC }, + .bits = {{ + .offset = 0, + .mask = MI_GLOBAL_GTT, + .expected = 0 + }}, + .bits_count = 1 ), + CMD( MI_LOAD_REGISTER_MEM, SMI, !F, 0xFF, W | B, + .reg = { .offset = 1, .mask = 0x007FFFFC }, + .bits = {{ + .offset = 0, + .mask = MI_GLOBAL_GTT, + .expected = 0 + }}, + .bits_count = 1 ), CMD( MI_BATCH_BUFFER_START, SMI, !F, 0xFF, S ), }; @@ -79,7 +97,20 @@ static const struct drm_i915_cmd_descriptor render_cmds[] = { CMD( MI_DISPLAY_FLIP, SMI, !F, 0xFF, R ), CMD( MI_PREDICATE, SMI, F, 1, S ), CMD( MI_TOPOLOGY_FILTER, SMI, F, 1, S ), - CMD( MI_CLFLUSH, SMI, !F, 0x3FF, S ), + CMD( MI_CLFLUSH, SMI, !F, 0x3FF, B, + .bits = {{ + .offset = 0, + .mask = MI_GLOBAL_GTT, + .expected = 0 + }}, + .bits_count = 1 ), + CMD( MI_CONDITIONAL_BATCH_BUFFER_END, SMI, !F, 0xFF, B, + .bits = {{ + .offset = 0, + .mask = MI_GLOBAL_GTT, + .expected = 0 + }}, + .bits_count = 1 ), CMD( GFX_OP_3DSTATE_VF_STATISTICS, S3D, F, 1, S ), CMD( PIPELINE_SELECT, S3D, F, 1, S ), CMD( MEDIA_VFE_STATE, S3D, !F, 0xFFFF, B, @@ -97,8 +128,15 @@ static const struct drm_i915_cmd_descriptor render_cmds[] = { .offset = 1, .mask = (PIPE_CONTROL_MMIO_WRITE | PIPE_CONTROL_NOTIFY), .expected = 0 + }, + { + .offset = 1, + .mask = PIPE_CONTROL_GLOBAL_GTT_IVB, + .expected = 0, + .condition_offset = 1, + .condition_mask = PIPE_CONTROL_POST_SYNC_OP_MASK }}, - .bits_count = 1 ), + .bits_count = 2 ), }; static const struct drm_i915_cmd_descriptor hsw_render_cmds[] = { @@ -122,8 +160,22 @@ static const struct drm_i915_cmd_descriptor video_cmds[] = { .offset = 0, .mask = MI_FLUSH_DW_NOTIFY, .expected = 0 + }, + { + .offset = 1, + .mask = MI_FLUSH_DW_USE_GTT, + .expected = 0, + .condition_offset = 0, + .condition_mask = MI_FLUSH_DW_OP_MASK }}, - .bits_count = 1 ), + .bits_count = 2 ), + CMD( MI_CONDITIONAL_BATCH_BUFFER_END, SMI, !F, 0xFF, B, + .bits = {{ + .offset = 0, + .mask = MI_GLOBAL_GTT, + .expected = 0 + }}, + .bits_count = 1 ), CMD( MFX_WAIT, SMFX, !F, 0x3F, S ), }; @@ -133,8 +185,22 @@ static const struct drm_i915_cmd_descriptor vecs_cmds[] = { .offset = 0, .mask = MI_FLUSH_DW_NOTIFY, .expected = 0 + }, + { + .offset = 1, + .mask = MI_FLUSH_DW_USE_GTT, + .expected = 0, + .condition_offset = 0, + .condition_mask = MI_FLUSH_DW_OP_MASK }}, - .bits_count = 1 ), + .bits_count = 2 ), + CMD( MI_CONDITIONAL_BATCH_BUFFER_END, SMI, !F, 0xFF, B, + .bits = {{ + .offset = 0, + .mask = MI_GLOBAL_GTT, + .expected = 0 + }}, + .bits_count = 1 ), }; static const struct drm_i915_cmd_descriptor blt_cmds[] = { @@ -144,8 +210,15 @@ static const struct drm_i915_cmd_descriptor blt_cmds[] = { .offset = 0, .mask = MI_FLUSH_DW_NOTIFY, .expected = 0 + }, + { + .offset = 1, + .mask = MI_FLUSH_DW_USE_GTT, + .expected = 0, + .condition_offset = 0, + .condition_mask = MI_FLUSH_DW_OP_MASK }}, - .bits_count = 1 ), + .bits_count = 2 ), CMD( COLOR_BLT, S2D, !F, 0x3F, S ), CMD( SRC_COPY_BLT, S2D, !F, 0x3F, S ), }; @@ -422,6 +495,13 @@ int i915_parse_cmds(struct intel_ring_buffer *ring, int ret = 0; u32 *cmd, *batch_base, *batch_end; struct drm_i915_cmd_descriptor default_desc = { 0 }; + drm_i915_private_t *dev_priv = + (drm_i915_private_t *)ring->dev->dev_private; + + /* XXX: this breaks VLV, which is Gen7, but no PPGTT + * Replace with better checks for when to call i915_parse_cmds? + */ + WARN_ON(!dev_priv->mm.aliasing_ppgtt); /* No command tables currently indicates a platform without parsing */ if (!ring->cmd_tables) @@ -490,6 +570,16 @@ int i915_parse_cmds(struct intel_ring_buffer *ring, u32 dword = cmd[desc->bits[i].offset] & desc->bits[i].mask; + if (desc->bits[i].condition_mask != 0) { + u32 offset = + desc->bits[i].condition_offset; + u32 condition = cmd[offset] & + desc->bits[i].condition_mask; + + if (condition == 0) + continue; + } + if (dword != desc->bits[i].expected) { DRM_DEBUG_DRIVER("CMD: Rejected command 0x%08X for bitmask 0x%08X (exp=0x%08X act=0x%08X) (ring=%d)\n", *cmd, diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index f31fc68..161d9cd 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1792,11 +1792,17 @@ struct drm_i915_cmd_descriptor { * compared against an expected value. If the command does not match * the expected value, the parser rejects it. Only valid if flags has * the CMD_DESC_BITMASK bit set. + * + * If the check specifies a non-zero condition_mask then the parser + * only performs the check when the bits specified by condition_mask + * are non-zero. */ struct { u32 offset; u32 mask; u32 expected; + u32 condition_offset; + u32 condition_mask; } bits[MAX_CMD_DESC_BITMASKS]; /** Number of valid entries in the bits array */ int bits_count; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 0e504b9..3f64d41 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -178,6 +178,8 @@ * Memory interface instructions used by the kernel */ #define MI_INSTR(opcode, flags) (((opcode) << 23) | (flags)) +/* Many MI commands use bit 22 of the header dword for GGTT vs PPGTT */ +#define MI_GLOBAL_GTT (1<<22) #define MI_NOOP MI_INSTR(0, 0) #define MI_USER_INTERRUPT MI_INSTR(0x02, 0) @@ -240,6 +242,7 @@ #define MI_FLUSH_DW_STORE_INDEX (1<<21) #define MI_INVALIDATE_TLB (1<<18) #define MI_FLUSH_DW_OP_STOREDW (1<<14) +#define MI_FLUSH_DW_OP_MASK (3<<14) #define MI_FLUSH_DW_NOTIFY (1<<8) #define MI_INVALIDATE_BSD (1<<7) #define MI_FLUSH_DW_USE_GTT (1<<2) @@ -323,6 +326,7 @@ #define PIPE_CONTROL_CS_STALL (1<<20) #define PIPE_CONTROL_TLB_INVALIDATE (1<<18) #define PIPE_CONTROL_QW_WRITE (1<<14) +#define PIPE_CONTROL_POST_SYNC_OP_MASK (3<<14) #define PIPE_CONTROL_DEPTH_STALL (1<<13) #define PIPE_CONTROL_WRITE_FLUSH (1<<12) #define PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH (1<<12) /* gen6+ */ @@ -354,6 +358,7 @@ #define MI_LOAD_REGISTER_REG MI_INSTR(0x2A, 0) #define MI_LOAD_URB_MEM MI_INSTR(0x2C, 0) #define MI_STORE_URB_MEM MI_INSTR(0x2D, 0) +#define MI_CONDITIONAL_BATCH_BUFFER_END MI_INSTR(0x36, 0) #define PIPELINE_SELECT ((0x3<<29)|(0x1<<27)|(0x1<<24)|(0x4<<16)) #define GFX_OP_3DSTATE_VF_STATISTICS ((0x3<<29)|(0x1<<27)|(0x0<<24)|(0xB<<16))