VMware SVGA II: 3.12-rc6

git-svn-id: svn://kolibrios.org@4111 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge) 2013-10-27 04:53:36 +00:00
parent 6e63c7609b
commit 737ef03421
11 changed files with 272 additions and 175 deletions

View File

@ -55,6 +55,7 @@ NAME_SRC= \
vmwgfx_scrn.c \
vmwgfx_surface.c \
vmwgfx_ttm_glue.c \
../hdmi.c \
../i2c/i2c-core.c \
../ttm/ttm_bo.c \
../ttm/ttm_bo_manager.c \
@ -63,15 +64,19 @@ NAME_SRC= \
../ttm/ttm_object.c \
../ttm/ttm_page_alloc.c \
../ttm/ttm_tt.c \
$(DRM_TOPDIR)/drm_crtc.c \
$(DRM_TOPDIR)/drm_crtc_helper.c \
$(DRM_TOPDIR)/drm_edid.c \
$(DRM_TOPDIR)/drm_global.c \
$(DRM_TOPDIR)/drm_hashtab.c \
$(DRM_TOPDIR)/drm_irq.c \
$(DRM_TOPDIR)/drm_mm.c \
$(DRM_TOPDIR)/drm_modes.c \
$(DRM_TOPDIR)/drm_stub.c
../drm_crtc.c \
../drm_crtc_helper.c \
../drm_drv.c \
../drm_edid.c \
../drm_gem.c \
../drm_global.c \
../drm_hashtab.c \
../drm_irq.c \
../drm_mm.c \
../drm_modes.c \
../drm_pci.c \
../drm_stub.c \
../drm_vma_manager.c

View File

@ -0,0 +1,106 @@
CC = gcc
LD = ld
AS = as
FASM = fasm.exe
DEFINES = -D__KERNEL__ -DCONFIG_X86_32
DRV_TOPDIR = $(CURDIR)/../../..
DRM_TOPDIR = $(CURDIR)/..
DRV_INCLUDES = $(DRV_TOPDIR)/include
INCLUDES = -I$(DRV_INCLUDES) -I$(DRV_INCLUDES)/drm \
-I$(DRV_INCLUDES)/linux
CFLAGS_OPT = -Os -march=i686 -msse2 -fomit-frame-pointer -fno-builtin-printf -mno-stack-arg-probe
CFLAGS_OPT+= -mpreferred-stack-boundary=2 -mincoming-stack-boundary=2 -mno-ms-bitfields -flto
CFLAGS = -c $(INCLUDES) $(DEFINES) $(CFLAGS_OPT)
LIBPATH:= $(DRV_TOPDIR)/ddk
LIBS:= -lddk -lcore -lgcc
LDFLAGS = -e,_drvEntry,-nostdlib,-shared,-s,--image-base,0,--file-alignment,512,--section-alignment,4096
NAME:= vmwgfx
HFILES:= $(DRV_INCLUDES)/linux/types.h \
$(DRV_INCLUDES)/linux/list.h \
$(DRV_INCLUDES)/linux/pci.h \
$(DRV_INCLUDES)/drm/drm.h \
$(DRV_INCLUDES)/drm/drmP.h \
$(DRV_INCLUDES)/drm/drm_edid.h \
$(DRV_INCLUDES)/drm/drm_crtc.h \
$(DRV_INCLUDES)/drm/drm_mode.h \
$(DRV_INCLUDES)/drm/drm_mm.h
NAME_SRC= \
main.c \
pci.c \
vmwgfx_buffer.c \
vmwgfx_context.c \
vmwgfx_dmabuf.c \
vmwgfx_drv.c \
vmwgfx_execbuf.c \
vmwgfx_fence.c \
vmwgfx_fifo.c \
vmwgfx_gmr.c \
vmwgfx_gmrid_manager.c \
vmwgfx_irq.c \
vmwgfx_kms.c \
vmwgfx_marker.c \
vmwgfx_resource.c \
vmwgfx_scrn.c \
vmwgfx_surface.c \
vmwgfx_ttm_glue.c \
../hdmi.c \
../i2c/i2c-core.c \
../ttm/ttm_bo.c \
../ttm/ttm_bo_manager.c \
../ttm/ttm_execbuf_util.c \
../ttm/ttm_memory.c \
../ttm/ttm_object.c \
../ttm/ttm_page_alloc.c \
../ttm/ttm_tt.c \
../drm_crtc.c \
../drm_crtc_helper.c \
../drm_drv.c \
../drm_edid.c \
../drm_gem.c \
../drm_global.c \
../drm_hashtab.c \
../drm_irq.c \
../drm_mm.c \
../drm_modes.c \
../drm_pci.c \
../drm_stub.c \
../drm_vma_manager.c
NAME_OBJS = $(patsubst %.S, %.o, $(patsubst %.asm, %.o,\
$(patsubst %.c, %.o, $(NAME_SRC))))
all: $(NAME).dll
$(NAME).dll: $(NAME_OBJS) $(SRC_DEP) $(HFILES) vmw.lds Makefile
$(CC) $(CFLAGS_OPT) -fwhole-program -nostdlib -Wl,-L$(LIBPATH),$(LDFLAGS),-T,vmw.lds -o $@ $(NAME_OBJS) libddk.a libcore.a libgcc.a
kpack $@
%.o : %.c $(HFILES) Makefile.lto
$(CC) $(CFLAGS) $(DEFINES) -o $@ $<
%.o : %.S $(HFILES) Makefile.lto
as -o $@ $<
clean:
-rm -f */*.o

View File

@ -26,10 +26,13 @@ struct pci_device {
uint8_t revision;
};
extern struct drm_device *main_device;
extern struct drm_file *drm_file_handlers[256];
struct drm_device *main_device;
struct drm_file *drm_file_handlers[256];
int vmw_init(void);
int kms_init(struct drm_device *dev);
void kms_update();
void cpu_detect();
void parse_cmdline(char *cmdline, char *log);
@ -61,6 +64,23 @@ unsigned int tsc_khz;
int kms_modeset = 1;
void vmw_driver_thread()
{
dbgprintf("%s\n",__FUNCTION__);
// run_workqueue(dev_priv->wq);
while(driver_wq_state)
{
kms_update();
delay(1);
};
__asm__ __volatile__ (
"int $0x40"
::"a"(-1));
}
u32_t __attribute__((externally_visible)) drvEntry(int action, char *cmdline)
{
@ -80,9 +100,9 @@ u32_t __attribute__((externally_visible)) drvEntry(int action, char *cmdline)
if(!dbg_open(log))
{
// strcpy(log, "/tmp1/1/vmw.log");
strcpy(log, "/tmp1/1/vmw.log");
// strcpy(log, "/RD/1/DRIVERS/VMW.log");
strcpy(log, "/HD0/1/vmw.log");
// strcpy(log, "/HD0/1/vmw.log");
if(!dbg_open(log))
{
@ -90,7 +110,7 @@ u32_t __attribute__((externally_visible)) drvEntry(int action, char *cmdline)
return 0;
};
}
dbgprintf(" vmw v3.10\n cmdline: %s\n", cmdline);
dbgprintf(" vmw v3.12-rc6\n cmdline: %s\n", cmdline);
cpu_detect();
dbgprintf("\ncache line size %d\n", x86_clflush_size);
@ -103,15 +123,16 @@ u32_t __attribute__((externally_visible)) drvEntry(int action, char *cmdline)
dbgprintf("Epic Fail :(\n");
return 0;
};
kms_init(main_device);
err = RegService("DISPLAY", display_handler);
if( err != 0)
dbgprintf("Set DISPLAY handler\n");
// struct drm_i915_private *dev_priv = main_device->dev_private;
// driver_wq_state = 1;
// run_workqueue(dev_priv->wq);
driver_wq_state = 1;
CreateKernelThread(vmw_driver_thread);
return err;
};
@ -446,26 +467,8 @@ void get_pci_info(struct pci_device *dev)
#include <ddk.h>
#include <linux/mm.h>
#include <drm/drmP.h>
#include <linux/hdmi.h>
#include <linux/ctype.h>
/**
* hdmi_avi_infoframe_init() - initialize an HDMI AVI infoframe
* @frame: HDMI AVI infoframe
*
* Returns 0 on success or a negative error code on failure.
*/
int hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame)
{
memset(frame, 0, sizeof(*frame));
frame->type = HDMI_INFOFRAME_TYPE_AVI;
frame->version = 2;
frame->length = 13;
return 0;
}
static void *check_bytes8(const u8 *start, u8 value, unsigned int bytes)
{
@ -873,10 +876,9 @@ struct tag_display
u32 mask_seqno;
u32 check_mouse;
u32 check_m_pixel;
u32 dirty;
void (*update)(void);
};
static display_t *os_display;
static int count_connector_modes(struct drm_connector* connector)
@ -941,7 +943,7 @@ int kms_init(struct drm_device *dev)
os_display->connector = connector;
os_display->crtc = crtc;
os_display->supported_modes = mode_count;
os_display->update = kms_update;
// os_display->update = kms_update;
// struct intel_crtc *intel_crtc = to_intel_crtc(os_display->crtc);
@ -965,8 +967,6 @@ int kms_init(struct drm_device *dev)
};
safe_sti(ifl);
main_device = dev;
#ifdef __HWA__
err = init_bitmaps();
#endif
@ -1069,3 +1069,57 @@ int set_user_mode(videomode_t *mode)
return err;
};
struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags)
{
struct file *filep;
int count;
filep = malloc(sizeof(*filep));
if(unlikely(filep == NULL))
return ERR_PTR(-ENOMEM);
count = size / PAGE_SIZE;
filep->pages = kzalloc(sizeof(struct page *) * count, 0);
if(unlikely(filep->pages == NULL))
{
kfree(filep);
return ERR_PTR(-ENOMEM);
};
filep->count = count;
filep->allocated = 0;
filep->vma = NULL;
// printf("%s file %p pages %p count %d\n",
// __FUNCTION__,filep, filep->pages, count);
return filep;
}
struct page *shmem_read_mapping_page_gfp(struct file *filep,
pgoff_t index, gfp_t gfp)
{
struct page *page;
// dbgprintf("%s, file %p index %d\n", __FUNCTION__, filep, index);
if(unlikely(index >= filep->count))
return ERR_PTR(-EINVAL);
page = filep->pages[index];
if(unlikely(page == NULL))
{
page = (struct page *)AllocPage();
if(unlikely(page == NULL))
return ERR_PTR(-ENOMEM);
filep->pages[index] = page;
};
return page;
};

View File

@ -41,10 +41,6 @@
#define VMW_MIN_INITIAL_WIDTH 800
#define VMW_MIN_INITIAL_HEIGHT 600
struct drm_device *main_device;
struct drm_file *drm_file_handlers[256];
#if 0
/**
* Fully encoded drm commands. Might move to vmw_drm.h
@ -128,7 +124,7 @@ struct drm_file *drm_file_handlers[256];
* Ioctl definitions.
*/
static struct drm_ioctl_desc vmw_ioctls[] = {
static const struct drm_ioctl_desc vmw_ioctls[] = {
VMW_IOCTL_DEF(VMW_GET_PARAM, vmw_getparam_ioctl,
DRM_AUTH | DRM_UNLOCKED),
VMW_IOCTL_DEF(VMW_ALLOC_DMABUF, vmw_dmabuf_alloc_ioctl,
@ -616,8 +612,10 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
}
dev_priv->fman = vmw_fence_manager_init(dev_priv);
if (unlikely(dev_priv->fman == NULL))
if (unlikely(dev_priv->fman == NULL)) {
ret = -ENOMEM;
goto out_no_fman;
}
vmw_kms_save_vga(dev_priv);
#endif
@ -634,6 +632,8 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
// vmw_fb_init(dev_priv);
}
main_device = dev;
LEAVE();
return 0;
@ -777,7 +777,7 @@ static long vmw_unlocked_ioctl(struct file *filp, unsigned int cmd,
if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END)
&& (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) {
struct drm_ioctl_desc *ioctl =
const struct drm_ioctl_desc *ioctl =
&vmw_ioctls[nr - DRM_COMMAND_BASE];
if (unlikely(ioctl->cmd_drv != cmd)) {
@ -790,29 +790,12 @@ static long vmw_unlocked_ioctl(struct file *filp, unsigned int cmd,
return drm_ioctl(filp, cmd, arg);
}
static int vmw_firstopen(struct drm_device *dev)
{
struct vmw_private *dev_priv = vmw_priv(dev);
dev_priv->is_opened = true;
return 0;
}
static void vmw_lastclose(struct drm_device *dev)
{
struct vmw_private *dev_priv = vmw_priv(dev);
struct drm_crtc *crtc;
struct drm_mode_set set;
int ret;
/**
* Do nothing on the lastclose call from drm_unload.
*/
if (!dev_priv->is_opened)
return;
dev_priv->is_opened = false;
set.x = 0;
set.y = 0;
set.fb = NULL;
@ -1082,12 +1065,10 @@ static int vmw_pm_prepare(struct device *kdev)
#endif
static struct drm_driver driver = {
.driver_features = DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED |
DRIVER_MODESET,
// .load = vmw_driver_load,
.load = vmw_driver_load,
// .unload = vmw_driver_unload,
// .firstopen = vmw_firstopen,
// .lastclose = vmw_lastclose,
@ -1122,6 +1103,22 @@ static struct drm_driver driver = {
// .patchlevel = VMWGFX_DRIVER_PATCHLEVEL
};
#if 0
static struct pci_driver vmw_pci_driver = {
.name = VMWGFX_DRIVER_NAME,
.id_table = vmw_pci_id_list,
.probe = vmw_probe,
.remove = vmw_remove,
.driver = {
.pm = &vmw_pm_ops
}
};
static int vmw_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
return drm_get_pci_dev(pdev, ent, &driver);
}
#endif
int vmw_init(void)
{
@ -1138,100 +1135,18 @@ int vmw_init(void)
return -ENODEV;
};
drm_core_init();
DRM_INFO("device %x:%x\n", device.pci_dev.vendor,
device.pci_dev.device);
drm_global_init();
err = drm_get_dev(&device.pci_dev, ent);
err = drm_get_pci_dev(&device.pci_dev, ent, &driver);
LEAVE();
return err;
}
//module_init(vmwgfx_init);
//module_exit(vmwgfx_exit);
MODULE_AUTHOR("VMware Inc. and others");
MODULE_DESCRIPTION("Standalone drm driver for the VMware SVGA device");
MODULE_LICENSE("GPL and additional rights");
int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent)
{
static struct drm_device drm_dev;
static struct drm_file drm_file;
struct drm_device *dev;
struct drm_file *priv;
int ret;
dev = &drm_dev;
priv = &drm_file;
drm_file_handlers[0] = priv;
// ret = pci_enable_device(pdev);
// if (ret)
// goto err_g1;
pci_set_master(pdev);
// if ((ret = drm_fill_in_dev(dev, pdev, ent, driver))) {
// printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
// goto err_g2;
// }
dev->pdev = pdev;
dev->pci_device = pdev->device;
dev->pci_vendor = pdev->vendor;
INIT_LIST_HEAD(&dev->filelist);
INIT_LIST_HEAD(&dev->ctxlist);
INIT_LIST_HEAD(&dev->vmalist);
INIT_LIST_HEAD(&dev->maplist);
spin_lock_init(&dev->count_lock);
mutex_init(&dev->struct_mutex);
mutex_init(&dev->ctxlist_mutex);
INIT_LIST_HEAD(&priv->lhead);
INIT_LIST_HEAD(&priv->fbs);
INIT_LIST_HEAD(&priv->event_list);
init_waitqueue_head(&priv->event_wait);
priv->event_space = 4096; /* set aside 4k for event buffer */
idr_init(&priv->object_idr);
spin_lock_init(&priv->table_lock);
dev->driver = &driver;
if (dev->driver->open) {
ret = dev->driver->open(dev, priv);
if (ret < 0)
goto err_g4;
}
ret = vmw_driver_load(dev, ent->driver_data );
if (ret)
goto err_g4;
ret = kms_init(dev);
if (ret)
goto err_g4;
return 0;
err_g4:
//err_g3:
// if (drm_core_check_feature(dev, DRIVER_MODESET))
// drm_put_minor(&dev->control);
//err_g2:
// pci_disable_device(pdev);
//err_g1:
return ret;
}

View File

@ -340,7 +340,6 @@ struct vmw_private {
*/
bool stealth;
bool is_opened;
bool enable_fb;
/**
@ -782,6 +781,9 @@ static inline struct ttm_mem_global *vmw_mem_glob(struct vmw_private *dev_priv)
return (struct ttm_mem_global *) dev_priv->mem_global_ref.object;
}
extern struct drm_device *main_device;
extern struct drm_file *drm_file_handlers[256];
typedef struct
{
int width;

View File

@ -1352,7 +1352,6 @@ int vmw_execbuf_fence_commands(struct drm_file *file_priv,
return 0;
}
/**
* vmw_execbuf_copy_fence_user - copy fence object information to
* user-space.
@ -1596,8 +1595,6 @@ out_unlock:
return ret;
}
/**
* vmw_execbuf_unpin_panic - Idle the fifo and unpin the query buffer.
*

View File

@ -32,7 +32,9 @@
#include <drm/drmP.h>
#include <drm/ttm/ttm_bo_driver.h>
#define VMW_PPN_SIZE sizeof(unsigned long)
#define VMW_PPN_SIZE (sizeof(unsigned long))
/* A future safe maximum remap size. */
#define VMW_PPN_PER_REMAP ((31 * 1024) / VMW_PPN_SIZE)
static int vmw_gmr2_bind(struct vmw_private *dev_priv,
struct page *pages[],
@ -41,34 +43,46 @@ static int vmw_gmr2_bind(struct vmw_private *dev_priv,
{
SVGAFifoCmdDefineGMR2 define_cmd;
SVGAFifoCmdRemapGMR2 remap_cmd;
uint32_t define_size = sizeof(define_cmd) + 4;
uint32_t remap_size = VMW_PPN_SIZE * num_pages + sizeof(remap_cmd) + 4;
uint32_t *cmd;
uint32_t *cmd_orig;
uint32_t define_size = sizeof(define_cmd) + sizeof(*cmd);
uint32_t remap_num = num_pages / VMW_PPN_PER_REMAP + ((num_pages % VMW_PPN_PER_REMAP) > 0);
uint32_t remap_size = VMW_PPN_SIZE * num_pages + (sizeof(remap_cmd) + sizeof(*cmd)) * remap_num;
uint32_t remap_pos = 0;
uint32_t cmd_size = define_size + remap_size;
uint32_t i;
cmd_orig = cmd = vmw_fifo_reserve(dev_priv, define_size + remap_size);
cmd_orig = cmd = vmw_fifo_reserve(dev_priv, cmd_size);
if (unlikely(cmd == NULL))
return -ENOMEM;
define_cmd.gmrId = gmr_id;
define_cmd.numPages = num_pages;
*cmd++ = SVGA_CMD_DEFINE_GMR2;
memcpy(cmd, &define_cmd, sizeof(define_cmd));
cmd += sizeof(define_cmd) / sizeof(*cmd);
/*
* Need to split the command if there are too many
* pages that goes into the gmr.
*/
remap_cmd.gmrId = gmr_id;
remap_cmd.flags = (VMW_PPN_SIZE > sizeof(*cmd)) ?
SVGA_REMAP_GMR2_PPN64 : SVGA_REMAP_GMR2_PPN32;
remap_cmd.offsetPages = 0;
remap_cmd.numPages = num_pages;
*cmd++ = SVGA_CMD_DEFINE_GMR2;
memcpy(cmd, &define_cmd, sizeof(define_cmd));
cmd += sizeof(define_cmd) / sizeof(uint32);
while (num_pages > 0) {
unsigned long nr = min(num_pages, (unsigned long)VMW_PPN_PER_REMAP);
remap_cmd.offsetPages = remap_pos;
remap_cmd.numPages = nr;
*cmd++ = SVGA_CMD_REMAP_GMR2;
memcpy(cmd, &remap_cmd, sizeof(remap_cmd));
cmd += sizeof(remap_cmd) / sizeof(uint32);
cmd += sizeof(remap_cmd) / sizeof(*cmd);
for (i = 0; i < num_pages; ++i) {
for (i = 0; i < nr; ++i) {
if (VMW_PPN_SIZE <= 4)
*cmd = page_to_pfn(*pages++);
else
@ -77,7 +91,13 @@ static int vmw_gmr2_bind(struct vmw_private *dev_priv,
cmd += VMW_PPN_SIZE / sizeof(*cmd);
}
vmw_fifo_commit(dev_priv, define_size + remap_size);
num_pages -= nr;
remap_pos += nr;
}
BUG_ON(cmd != cmd_orig + cmd_size / sizeof(*cmd));
vmw_fifo_commit(dev_priv, cmd_size);
return 0;
}

View File

@ -123,7 +123,8 @@ struct vmw_display_unit {
void vmw_display_unit_cleanup(struct vmw_display_unit *du);
int vmw_du_page_flip(struct drm_crtc *crtc,
struct drm_framebuffer *fb,
struct drm_pending_vblank_event *event);
struct drm_pending_vblank_event *event,
uint32_t page_flip_flags);
void vmw_du_crtc_save(struct drm_crtc *crtc);
void vmw_du_crtc_restore(struct drm_crtc *crtc);
void vmw_du_crtc_gamma_set(struct drm_crtc *crtc,

View File

@ -501,7 +501,7 @@ int vmw_dmabuf_alloc_ioctl(struct drm_device *dev, void *data,
goto out_no_dmabuf;
rep->handle = handle;
rep->map_handle = dma_buf->base.addr_space_offset;
rep->map_handle = drm_vma_node_offset_addr(&dma_buf->base.vma_node);
rep->cur_gmr_id = handle;
rep->cur_gmr_offset = 0;
@ -839,7 +839,7 @@ int vmw_dumb_map_offset(struct drm_file *file_priv,
if (ret != 0)
return -EINVAL;
*offset = out_buf->base.addr_space_offset;
*offset = drm_vma_node_offset_addr(&out_buf->base.vma_node);
vmw_dmabuf_unreference(&out_buf);
return 0;
}

View File

@ -629,13 +629,11 @@ struct tag_display
void (*update)(void);
};
extern struct drm_device *main_device;
bool set_mode(struct drm_device *dev, struct drm_connector *connector,
videomode_t *reqmode, bool strict)
{
struct drm_display_mode *mode = NULL, *tmpmode;
struct vmw_private *dev_priv = vmw_priv(main_device);
struct vmw_private *dev_priv = vmw_priv(dev);
struct vmw_screen_object_unit *sou;
display_t *os_display;

View File

@ -26,7 +26,6 @@
**************************************************************************/
#include <drm/drmP.h>
#include <drm/drm_global.h>
#include "vmwgfx_drv.h"
#if 0