Commit f2a0dcb1 authored by Thomas Hellstrom's avatar Thomas Hellstrom

drm/vmwgfx: Implement 64-bit Otable- and MOB binding v2

Adds the relevant commands to the device interface header and
implements 64-bit binding for 64 bit VMs.

v2: Uppercase command IDs, Correctly use also 64 bit page tables.
Signed-off-by: default avatarThomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: default avatarJakob Bornecrantz <jakob@vmware.com>
parent b360a3ce
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include "svga_reg.h" #include "svga_reg.h"
typedef uint32 PPN; typedef uint32 PPN;
typedef __le64 PPN64;
/* /*
* 3D Hardware Version * 3D Hardware Version
...@@ -1200,7 +1201,7 @@ typedef enum { ...@@ -1200,7 +1201,7 @@ typedef enum {
#define SVGA_3D_CMD_DESTROY_GB_SHADER 1113 #define SVGA_3D_CMD_DESTROY_GB_SHADER 1113
#define SVGA_3D_CMD_BIND_GB_SHADER 1114 #define SVGA_3D_CMD_BIND_GB_SHADER 1114
#define SVGA_3D_CMD_BIND_SHADERCONSTS 1115 #define SVGA_3D_CMD_SET_OTABLE_BASE64 1115
#define SVGA_3D_CMD_BEGIN_GB_QUERY 1116 #define SVGA_3D_CMD_BEGIN_GB_QUERY 1116
#define SVGA_3D_CMD_END_GB_QUERY 1117 #define SVGA_3D_CMD_END_GB_QUERY 1117
...@@ -1223,7 +1224,10 @@ typedef enum { ...@@ -1223,7 +1224,10 @@ typedef enum {
#define SVGA_3D_CMD_SET_GB_SHADERCONSTS_INLINE 1130 #define SVGA_3D_CMD_SET_GB_SHADERCONSTS_INLINE 1130
#define SVGA_3D_CMD_MAX 1131 #define SVGA_3D_CMD_DEFINE_GB_MOB64 1135
#define SVGA_3D_CMD_REDEFINE_GB_MOB64 1136
#define SVGA_3D_CMD_MAX 1142
#define SVGA_3D_CMD_FUTURE_MAX 3000 #define SVGA_3D_CMD_FUTURE_MAX 3000
/* /*
...@@ -1927,6 +1931,9 @@ typedef enum SVGAMobFormat { ...@@ -1927,6 +1931,9 @@ typedef enum SVGAMobFormat {
SVGA3D_MOBFMT_PTDEPTH_1 = 1, SVGA3D_MOBFMT_PTDEPTH_1 = 1,
SVGA3D_MOBFMT_PTDEPTH_2 = 2, SVGA3D_MOBFMT_PTDEPTH_2 = 2,
SVGA3D_MOBFMT_RANGE = 3, SVGA3D_MOBFMT_RANGE = 3,
SVGA3D_MOBFMT_PTDEPTH64_0 = 4,
SVGA3D_MOBFMT_PTDEPTH64_1 = 5,
SVGA3D_MOBFMT_PTDEPTH64_2 = 6,
SVGA3D_MOBFMT_MAX, SVGA3D_MOBFMT_MAX,
} SVGAMobFormat; } SVGAMobFormat;
...@@ -1968,6 +1975,15 @@ struct { ...@@ -1968,6 +1975,15 @@ struct {
SVGAMobFormat ptDepth; SVGAMobFormat ptDepth;
} SVGA3dCmdSetOTableBase; /* SVGA_3D_CMD_SET_OTABLE_BASE */ } SVGA3dCmdSetOTableBase; /* SVGA_3D_CMD_SET_OTABLE_BASE */
typedef
struct {
SVGAOTableType type;
PPN64 baseAddress;
uint32 sizeInBytes;
uint32 validSizeInBytes;
SVGAMobFormat ptDepth;
} SVGA3dCmdSetOTableBase64; /* SVGA_3D_CMD_SET_OTABLE_BASE64 */
typedef typedef
struct { struct {
SVGAOTableType type; SVGAOTableType type;
...@@ -2007,6 +2023,32 @@ struct SVGA3dCmdRedefineGBMob { ...@@ -2007,6 +2023,32 @@ struct SVGA3dCmdRedefineGBMob {
uint32 sizeInBytes; uint32 sizeInBytes;
} SVGA3dCmdRedefineGBMob; /* SVGA_3D_CMD_REDEFINE_GB_MOB */ } SVGA3dCmdRedefineGBMob; /* SVGA_3D_CMD_REDEFINE_GB_MOB */
/*
* Define a memory object (Mob) in the OTable with a PPN64 base.
*/
typedef
struct SVGA3dCmdDefineGBMob64 {
SVGAMobId mobid;
SVGAMobFormat ptDepth;
PPN64 base;
uint32 sizeInBytes;
}
SVGA3dCmdDefineGBMob64; /* SVGA_3D_CMD_DEFINE_GB_MOB64 */
/*
* Redefine an object in the OTable with PPN64 base.
*/
typedef
struct SVGA3dCmdRedefineGBMob64 {
SVGAMobId mobid;
SVGAMobFormat ptDepth;
PPN64 base;
uint32 sizeInBytes;
}
SVGA3dCmdRedefineGBMob64; /* SVGA_3D_CMD_REDEFINE_GB_MOB64 */
/* /*
* Notification that the page tables have been modified. * Notification that the page tables have been modified.
*/ */
...@@ -2243,14 +2285,6 @@ typedef struct SVGA3dCmdDestroyGBShader { ...@@ -2243,14 +2285,6 @@ typedef struct SVGA3dCmdDestroyGBShader {
uint32 shid; uint32 shid;
} SVGA3dCmdDestroyGBShader; /* SVGA_3D_CMD_DESTROY_GB_SHADER */ } SVGA3dCmdDestroyGBShader; /* SVGA_3D_CMD_DESTROY_GB_SHADER */
typedef struct SVGA3dCmdBindGBShaderConsts {
uint32 cid;
SVGA3dShaderType shaderType;
SVGA3dShaderConstType shaderConstType;
uint32 sid;
} SVGA3dCmdBindGBShaderConsts; /* SVGA_3D_CMD_BIND_SHADERCONSTS */
typedef typedef
struct { struct {
uint32 cid; uint32 cid;
......
...@@ -1730,7 +1730,7 @@ static const struct vmw_cmd_entry const vmw_cmd_entries[SVGA_3D_CMD_MAX] = { ...@@ -1730,7 +1730,7 @@ static const struct vmw_cmd_entry const vmw_cmd_entries[SVGA_3D_CMD_MAX] = {
true, false, true), true, false, true),
VMW_CMD_DEF(SVGA_3D_CMD_DESTROY_GB_SHADER, &vmw_cmd_invalid, VMW_CMD_DEF(SVGA_3D_CMD_DESTROY_GB_SHADER, &vmw_cmd_invalid,
false, false, true), false, false, true),
VMW_CMD_DEF(SVGA_3D_CMD_BIND_SHADERCONSTS, &vmw_cmd_invalid, VMW_CMD_DEF(SVGA_3D_CMD_SET_OTABLE_BASE64, &vmw_cmd_invalid,
false, false, false), false, false, false),
VMW_CMD_DEF(SVGA_3D_CMD_BEGIN_GB_QUERY, &vmw_cmd_begin_gb_query, VMW_CMD_DEF(SVGA_3D_CMD_BEGIN_GB_QUERY, &vmw_cmd_begin_gb_query,
true, false, true), true, false, true),
......
...@@ -33,13 +33,25 @@ ...@@ -33,13 +33,25 @@
#define VMW_OTABLE_SETUP_SUB ((VMWGFX_ENABLE_SCREEN_TARGET_OTABLE) ? 0 : 1) #define VMW_OTABLE_SETUP_SUB ((VMWGFX_ENABLE_SCREEN_TARGET_OTABLE) ? 0 : 1)
/* #ifdef CONFIG_64BIT
* Currently the MOB interface does not support 64-bit page frame numbers. #define VMW_PPN_SIZE 8
* This might change in the future to be similar to the GMR2 interface #define vmw_cmd_set_otable_base SVGA3dCmdSetOTableBase64
* when virtual machines support memory beyond 16TB. #define VMW_ID_SET_OTABLE_BASE SVGA_3D_CMD_SET_OTABLE_BASE64
*/ #define vmw_cmd_define_gb_mob SVGA3dCmdDefineGBMob64
#define VMW_ID_DEFINE_GB_MOB SVGA_3D_CMD_DEFINE_GB_MOB64
#define VMW_MOBFMT_PTDEPTH_0 SVGA3D_MOBFMT_PTDEPTH64_0
#define VMW_MOBFMT_PTDEPTH_1 SVGA3D_MOBFMT_PTDEPTH64_1
#define VMW_MOBFMT_PTDEPTH_2 SVGA3D_MOBFMT_PTDEPTH64_2
#else
#define VMW_PPN_SIZE 4 #define VMW_PPN_SIZE 4
#define vmw_cmd_set_otable_base SVGA3dCmdSetOTableBase
#define VMW_ID_SET_OTABLE_BASE SVGA_3D_CMD_SET_OTABLE_BASE
#define vmw_cmd_define_gb_mob SVGA3dCmdDefineGBMob
#define VMW_ID_DEFINE_GB_MOB SVGA_3D_CMD_DEFINE_GB_MOB
#define VMW_MOBFMT_PTDEPTH_0 SVGA3D_MOBFMT_PTDEPTH_0
#define VMW_MOBFMT_PTDEPTH_1 SVGA3D_MOBFMT_PTDEPTH_1
#define VMW_MOBFMT_PTDEPTH_2 SVGA3D_MOBFMT_PTDEPTH_2
#endif
/* /*
* struct vmw_mob - Structure containing page table and metadata for a * struct vmw_mob - Structure containing page table and metadata for a
...@@ -93,7 +105,7 @@ static int vmw_setup_otable_base(struct vmw_private *dev_priv, ...@@ -93,7 +105,7 @@ static int vmw_setup_otable_base(struct vmw_private *dev_priv,
{ {
struct { struct {
SVGA3dCmdHeader header; SVGA3dCmdHeader header;
SVGA3dCmdSetOTableBase body; vmw_cmd_set_otable_base body;
} *cmd; } *cmd;
struct vmw_mob *mob; struct vmw_mob *mob;
const struct vmw_sg_table *vsgt; const struct vmw_sg_table *vsgt;
...@@ -113,7 +125,7 @@ static int vmw_setup_otable_base(struct vmw_private *dev_priv, ...@@ -113,7 +125,7 @@ static int vmw_setup_otable_base(struct vmw_private *dev_priv,
} }
if (otable->size <= PAGE_SIZE) { if (otable->size <= PAGE_SIZE) {
mob->pt_level = SVGA3D_MOBFMT_PTDEPTH_0; mob->pt_level = VMW_MOBFMT_PTDEPTH_0;
mob->pt_root_page = vmw_piter_dma_addr(&iter); mob->pt_root_page = vmw_piter_dma_addr(&iter);
} else if (vsgt->num_regions == 1) { } else if (vsgt->num_regions == 1) {
mob->pt_level = SVGA3D_MOBFMT_RANGE; mob->pt_level = SVGA3D_MOBFMT_RANGE;
...@@ -124,6 +136,7 @@ static int vmw_setup_otable_base(struct vmw_private *dev_priv, ...@@ -124,6 +136,7 @@ static int vmw_setup_otable_base(struct vmw_private *dev_priv,
goto out_no_populate; goto out_no_populate;
vmw_mob_pt_setup(mob, iter, otable->size >> PAGE_SHIFT); vmw_mob_pt_setup(mob, iter, otable->size >> PAGE_SHIFT);
mob->pt_level += VMW_MOBFMT_PTDEPTH_1 - SVGA3D_MOBFMT_PTDEPTH_1;
} }
cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
...@@ -133,7 +146,7 @@ static int vmw_setup_otable_base(struct vmw_private *dev_priv, ...@@ -133,7 +146,7 @@ static int vmw_setup_otable_base(struct vmw_private *dev_priv,
} }
memset(cmd, 0, sizeof(*cmd)); memset(cmd, 0, sizeof(*cmd));
cmd->header.id = SVGA_3D_CMD_SET_OTABLE_BASE; cmd->header.id = VMW_ID_SET_OTABLE_BASE;
cmd->header.size = sizeof(cmd->body); cmd->header.size = sizeof(cmd->body);
cmd->body.type = type; cmd->body.type = type;
cmd->body.baseAddress = mob->pt_root_page >> PAGE_SHIFT; cmd->body.baseAddress = mob->pt_root_page >> PAGE_SHIFT;
...@@ -141,6 +154,13 @@ static int vmw_setup_otable_base(struct vmw_private *dev_priv, ...@@ -141,6 +154,13 @@ static int vmw_setup_otable_base(struct vmw_private *dev_priv,
cmd->body.validSizeInBytes = 0; cmd->body.validSizeInBytes = 0;
cmd->body.ptDepth = mob->pt_level; cmd->body.ptDepth = mob->pt_level;
/*
* The device doesn't support this, But the otable size is
* determined at compile-time, so this BUG shouldn't trigger
* randomly.
*/
BUG_ON(mob->pt_level == VMW_MOBFMT_PTDEPTH_2);
vmw_fifo_commit(dev_priv, sizeof(*cmd)); vmw_fifo_commit(dev_priv, sizeof(*cmd));
otable->page_table = mob; otable->page_table = mob;
...@@ -403,6 +423,27 @@ static int vmw_mob_pt_populate(struct vmw_private *dev_priv, ...@@ -403,6 +423,27 @@ static int vmw_mob_pt_populate(struct vmw_private *dev_priv,
return ret; return ret;
} }
/**
* vmw_mob_assign_ppn - Assign a value to a page table entry
*
* @addr: Pointer to pointer to page table entry.
* @val: The page table entry
*
* Assigns a value to a page table entry pointed to by *@addr and increments
* *@addr according to the page table entry size.
*/
#if (VMW_PPN_SIZE == 8)
static void vmw_mob_assign_ppn(uint32_t **addr, dma_addr_t val)
{
*((uint64_t *) *addr) = val >> PAGE_SHIFT;
*addr += 2;
}
#else
static void vmw_mob_assign_ppn(uint32_t **addr, dma_addr_t val)
{
*(*addr)++ = val >> PAGE_SHIFT;
}
#endif
/* /*
* vmw_mob_build_pt - Build a pagetable * vmw_mob_build_pt - Build a pagetable
...@@ -432,8 +473,8 @@ static unsigned long vmw_mob_build_pt(struct vmw_piter *data_iter, ...@@ -432,8 +473,8 @@ static unsigned long vmw_mob_build_pt(struct vmw_piter *data_iter,
save_addr = addr = kmap_atomic(page); save_addr = addr = kmap_atomic(page);
for (i = 0; i < PAGE_SIZE / VMW_PPN_SIZE; ++i) { for (i = 0; i < PAGE_SIZE / VMW_PPN_SIZE; ++i) {
u32 tmp = vmw_piter_dma_addr(data_iter) >> PAGE_SHIFT; vmw_mob_assign_ppn(&addr,
*addr++ = tmp; vmw_piter_dma_addr(data_iter));
if (unlikely(--num_data_pages == 0)) if (unlikely(--num_data_pages == 0))
break; break;
WARN_ON(!vmw_piter_next(data_iter)); WARN_ON(!vmw_piter_next(data_iter));
...@@ -565,7 +606,7 @@ int vmw_mob_bind(struct vmw_private *dev_priv, ...@@ -565,7 +606,7 @@ int vmw_mob_bind(struct vmw_private *dev_priv,
struct vmw_piter data_iter; struct vmw_piter data_iter;
struct { struct {
SVGA3dCmdHeader header; SVGA3dCmdHeader header;
SVGA3dCmdDefineGBMob body; vmw_cmd_define_gb_mob body;
} *cmd; } *cmd;
mob->id = mob_id; mob->id = mob_id;
...@@ -574,7 +615,7 @@ int vmw_mob_bind(struct vmw_private *dev_priv, ...@@ -574,7 +615,7 @@ int vmw_mob_bind(struct vmw_private *dev_priv,
return 0; return 0;
if (likely(num_data_pages == 1)) { if (likely(num_data_pages == 1)) {
mob->pt_level = SVGA3D_MOBFMT_PTDEPTH_0; mob->pt_level = VMW_MOBFMT_PTDEPTH_0;
mob->pt_root_page = vmw_piter_dma_addr(&data_iter); mob->pt_root_page = vmw_piter_dma_addr(&data_iter);
} else if (vsgt->num_regions == 1) { } else if (vsgt->num_regions == 1) {
mob->pt_level = SVGA3D_MOBFMT_RANGE; mob->pt_level = SVGA3D_MOBFMT_RANGE;
...@@ -586,6 +627,7 @@ int vmw_mob_bind(struct vmw_private *dev_priv, ...@@ -586,6 +627,7 @@ int vmw_mob_bind(struct vmw_private *dev_priv,
vmw_mob_pt_setup(mob, data_iter, num_data_pages); vmw_mob_pt_setup(mob, data_iter, num_data_pages);
pt_set_up = true; pt_set_up = true;
mob->pt_level += VMW_MOBFMT_PTDEPTH_1 - SVGA3D_MOBFMT_PTDEPTH_1;
} }
(void) vmw_3d_resource_inc(dev_priv, false); (void) vmw_3d_resource_inc(dev_priv, false);
...@@ -597,7 +639,7 @@ int vmw_mob_bind(struct vmw_private *dev_priv, ...@@ -597,7 +639,7 @@ int vmw_mob_bind(struct vmw_private *dev_priv,
goto out_no_cmd_space; goto out_no_cmd_space;
} }
cmd->header.id = SVGA_3D_CMD_DEFINE_GB_MOB; cmd->header.id = VMW_ID_DEFINE_GB_MOB;
cmd->header.size = sizeof(cmd->body); cmd->header.size = sizeof(cmd->body);
cmd->body.mobid = mob_id; cmd->body.mobid = mob_id;
cmd->body.ptDepth = mob->pt_level; cmd->body.ptDepth = mob->pt_level;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment