This patch introduces the basic prototypes and definitions for GVT guest MMIO emulation. - Save an original MMIO snaphot when system boot up, which will be used as the initial guest MMIO content. - Introduce a framework to tracked all kinds of GEN MMIO registers, each tracked MMIO register may have a handler to emulate the HW registers change. Signed-off-by: Zhi Wang <zhi.a.wang@xxxxxxxxx> --- drivers/gpu/drm/i915/gvt/Makefile | 2 +- drivers/gpu/drm/i915/gvt/gvt.c | 9 ++ drivers/gpu/drm/i915/gvt/gvt.h | 127 ++++++++++++++++ drivers/gpu/drm/i915/gvt/handlers.c | 47 ++++++ drivers/gpu/drm/i915/gvt/mmio.c | 290 ++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/gvt/mmio.h | 87 +++++++++++ drivers/gpu/drm/i915/gvt/reg.h | 4 + 7 files changed, 565 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/i915/gvt/handlers.c create mode 100644 drivers/gpu/drm/i915/gvt/mmio.c create mode 100644 drivers/gpu/drm/i915/gvt/mmio.h diff --git a/drivers/gpu/drm/i915/gvt/Makefile b/drivers/gpu/drm/i915/gvt/Makefile index 6655929..5d28ed1 100644 --- a/drivers/gpu/drm/i915/gvt/Makefile +++ b/drivers/gpu/drm/i915/gvt/Makefile @@ -1,4 +1,4 @@ -GVT_SOURCE := gvt.o params.o aperture_gm.o fb_decoder.o +GVT_SOURCE := gvt.o params.o aperture_gm.o mmio.o handlers.o fb_decoder.o ccflags-y += -I$(src) -I$(src)/.. -Wall -Werror -Wno-unused-function i915_gvt-y := $(GVT_SOURCE) diff --git a/drivers/gpu/drm/i915/gvt/gvt.c b/drivers/gpu/drm/i915/gvt/gvt.c index f31e9f7..f5066bc 100644 --- a/drivers/gpu/drm/i915/gvt/gvt.c +++ b/drivers/gpu/drm/i915/gvt/gvt.c @@ -136,6 +136,8 @@ static void init_initial_cfg_space_state(struct pgt_device *pdev) static void clean_initial_mmio_state(struct pgt_device *pdev) { + gvt_clean_initial_mmio_state(pdev); + if (pdev->gttmmio_va) { iounmap(pdev->gttmmio_va); pdev->gttmmio_va = NULL; @@ -179,6 +181,9 @@ static bool init_initial_mmio_state(struct pgt_device *pdev) gvt_info("gttmmio_va: %p", pdev->gttmmio_va); gvt_info("gmadr_va: %p", pdev->gmadr_va); + if (!gvt_setup_initial_mmio_state(pdev)) + goto err; + return true; err: clean_initial_mmio_state(pdev); @@ -233,6 +238,7 @@ static bool init_service_thread(struct pgt_device *pdev) static void clean_pgt_device(struct pgt_device *pdev) { clean_service_thread(pdev); + gvt_clean_mmio_emulation_state(pdev); clean_initial_mmio_state(pdev); gvt_clean_resource_allocator(pdev); } @@ -249,6 +255,9 @@ static bool init_pgt_device(struct pgt_device *pdev, struct drm_i915_private *de gvt_init_resource_allocator(pdev); + if (!gvt_setup_mmio_emulation_state(pdev)) + goto err; + if (!init_service_thread(pdev)) goto err; diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h index aa4851c..798e216 100644 --- a/drivers/gpu/drm/i915/gvt/gvt.h +++ b/drivers/gpu/drm/i915/gvt/gvt.h @@ -33,6 +33,7 @@ #include "hypercall.h" #include "mpt.h" #include "fb_decoder.h" +#include "mmio.h" #define GVT_MAX_VGPU 8 @@ -41,6 +42,8 @@ #define GVT_MAX_NUM_FENCES 32 #define GVT_FENCE_BITMAP_BITS GVT_MAX_NUM_FENCES +#define GVT_HASH_BITS 9 + enum { GVT_HYPERVISOR_TYPE_XEN = 0, GVT_HYPERVISOR_TYPE_KVM, @@ -133,7 +136,16 @@ struct pgt_device { DECLARE_BITMAP(fence_bitmap, GVT_FENCE_BITMAP_BITS); u64 total_gm_sz; + struct gvt_gm_allocator gm_allocator; + + u32 *initial_mmio_state; + u32 *reg_info; + + gvt_aux_entry_t aux_table[GVT_AUX_TABLE_NUM]; + u32 aux_table_index; + + DECLARE_HASHTABLE(mmio_table, GVT_HASH_BITS); }; /* definitions for physical aperture/GM space */ @@ -200,6 +212,108 @@ extern int gvt_alloc_gm_and_fence_resource(struct vgt_device *vgt, struct gvt_instance_info *info); extern void gvt_free_gm_and_fence_resource(struct vgt_device *vgt); +#define REG_INDEX(reg) ((reg) >> 2) + +#define D_SNB (1 << 0) +#define D_IVB (1 << 1) +#define D_HSW (1 << 2) +#define D_BDW (1 << 3) + +#define D_GEN8PLUS (D_BDW) +#define D_GEN75PLUS (D_HSW | D_BDW) +#define D_GEN7PLUS (D_IVB | D_HSW | D_BDW) + +#define D_BDW_PLUS (D_BDW) +#define D_HSW_PLUS (D_HSW | D_BDW) +#define D_IVB_PLUS (D_IVB | D_HSW | D_BDW) + +#define D_PRE_BDW (D_SNB | D_IVB | D_HSW) + +#define D_ALL (D_SNB | D_IVB | D_HSW | D_BDW) + +#define reg_addr_fix(pdev, reg) (pdev->reg_info[REG_INDEX(reg)] & GVT_REG_ADDR_FIX) +#define reg_hw_status(pdev, reg) (pdev->reg_info[REG_INDEX(reg)] & GVT_REG_HW_STATUS) +#define reg_virt(pdev, reg) (pdev->reg_info[REG_INDEX(reg)] & GVT_REG_VIRT) +#define reg_mode_ctl(pdev, reg) (pdev->reg_info[REG_INDEX(reg)] & GVT_REG_MODE_CTL) +#define reg_is_tracked(pdev, reg) (pdev->reg_info[REG_INDEX(reg)] & GVT_REG_TRACKED) +#define reg_is_accessed(pdev, reg) (pdev->reg_info[REG_INDEX(reg)] & GVT_REG_ACCESSED) +#define reg_is_saved(pdev, reg) (pdev->reg_info[REG_INDEX(reg)] & GVT_REG_SAVED) + +#define reg_aux_index(pdev, reg) \ + ((pdev->reg_info[REG_INDEX(reg)] & GVT_REG_INDEX_MASK) >> GVT_REG_INDEX_SHIFT) +#define reg_has_aux_info(pdev, reg) (reg_mode_ctl(pdev, reg) | reg_addr_fix(pdev, reg)) +#define reg_aux_mode_mask(pdev, reg) \ + (pdev->aux_table[reg_aux_index(pdev, reg)].mode_ctl.mask) +#define reg_aux_addr_mask(pdev, reg) \ + (pdev->aux_table[reg_aux_index(pdev, reg)].addr_fix.mask) +#define reg_aux_addr_size(pdev, reg) \ + (pdev->aux_table[reg_aux_index(pdev, reg)].addr_fix.size) + +static inline void reg_set_hw_status(struct pgt_device *pdev, u32 reg) +{ + ASSERT_NUM(!reg_is_tracked(pdev, reg), reg); + pdev->reg_info[REG_INDEX(reg)] |= GVT_REG_HW_STATUS; +} + +static inline void reg_set_virt(struct pgt_device *pdev, u32 reg) +{ + ASSERT_NUM(!reg_is_tracked(pdev, reg), reg); + pdev->reg_info[REG_INDEX(reg)] |= GVT_REG_VIRT; +} + +/* mask bits for addr fix */ +static inline void reg_set_addr_fix(struct pgt_device *pdev, + u32 reg, u32 mask) +{ + ASSERT(!reg_has_aux_info(pdev, reg)); + ASSERT(pdev->aux_table_index <= GVT_AUX_TABLE_NUM - 1); + ASSERT_NUM(!reg_is_tracked(pdev, reg), reg); + + pdev->aux_table[pdev->aux_table_index].addr_fix.mask = mask; + pdev->reg_info[REG_INDEX(reg)] |= GVT_REG_ADDR_FIX | + (pdev->aux_table_index << GVT_REG_INDEX_SHIFT); + pdev->aux_table_index++; +} + +/* mask bits for mode mask */ +static inline void reg_set_mode_ctl(struct pgt_device *pdev, + u32 reg) +{ + ASSERT(!reg_has_aux_info(pdev, reg)); + ASSERT(pdev->aux_table_index <= GVT_AUX_TABLE_NUM - 1); + ASSERT_NUM(!reg_is_tracked(pdev, reg), reg); + + pdev->reg_info[REG_INDEX(reg)] |= GVT_REG_MODE_CTL | + (pdev->aux_table_index << GVT_REG_INDEX_SHIFT); + pdev->aux_table_index++; +} + +static inline void reg_set_tracked(struct pgt_device *pdev, + u32 reg) +{ + ASSERT_NUM(!reg_is_tracked(pdev, reg), reg); + pdev->reg_info[REG_INDEX(reg)] |= GVT_REG_TRACKED; +} + +static inline void reg_set_accessed(struct pgt_device *pdev, + u32 reg) +{ + pdev->reg_info[REG_INDEX(reg)] |= GVT_REG_ACCESSED; +} + +static inline void reg_set_saved(struct pgt_device *pdev, + u32 reg) +{ + pdev->reg_info[REG_INDEX(reg)] |= GVT_REG_SAVED; +} + +static inline void reg_set_cmd_access(struct pgt_device *pdev, + u32 reg) +{ + pdev->reg_info[REG_INDEX(reg)] |= GVT_REG_CMD_ACCESS; + reg_set_accessed(pdev, reg); +} + static inline u32 gvt_mmio_read(struct pgt_device *pdev, u32 reg) { @@ -232,4 +346,17 @@ static inline void gvt_mmio_write64(struct pgt_device *pdev, I915_WRITE64(tmp, val); } +static inline void gvt_mmio_posting_read(struct pgt_device *pdev, u32 reg) +{ + struct drm_i915_private *dev_priv = pdev->dev_priv; + i915_reg_t tmp = {.reg = reg}; + POSTING_READ(tmp); +} + +extern void gvt_clean_initial_mmio_state(struct pgt_device *pdev); +extern bool gvt_setup_initial_mmio_state(struct pgt_device *pdev); + +extern void gvt_clean_mmio_emulation_state(struct pgt_device *pdev); +extern bool gvt_setup_mmio_emulation_state(struct pgt_device *pdev); + #endif diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c new file mode 100644 index 0000000..a6ec4f3 --- /dev/null +++ b/drivers/gpu/drm/i915/gvt/handlers.c @@ -0,0 +1,47 @@ +/* + * Copyright(c) 2011-2016 Intel Corporation. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "gvt.h" + +/* TODO: Merge register definition from i915. */ +struct gvt_reg_info gvt_general_reg_info[] = { +{0, 0, 0, 0, 0, NULL, NULL}, +}; + +struct gvt_reg_info gvt_broadwell_reg_info[] = { +{0, 0, 0, 0, 0, NULL, NULL}, +}; + +int gvt_get_reg_num(int type) +{ + switch(type){ + case D_ALL: + return ARRAY_SIZE(gvt_general_reg_info); + case D_BDW: + return ARRAY_SIZE(gvt_broadwell_reg_info); + default: + return 0; + } + + return 0; +} diff --git a/drivers/gpu/drm/i915/gvt/mmio.c b/drivers/gpu/drm/i915/gvt/mmio.c new file mode 100644 index 0000000..0fbabd2 --- /dev/null +++ b/drivers/gpu/drm/i915/gvt/mmio.c @@ -0,0 +1,290 @@ +/* + * Copyright(c) 2011-2016 Intel Corporation. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "gvt.h" + +static inline unsigned int get_device_type(struct pgt_device *pdev) +{ + if (IS_BROADWELL(pdev->dev_priv)) + return D_BDW; + return 0; +} + +static inline bool match_device(struct pgt_device *pdev, struct gvt_reg_info *info) +{ + return info->device & get_device_type(pdev); +} + +static void save_initial_mmio_state(struct pgt_device *pdev, + struct gvt_reg_info *info, int num) +{ + u32 *mmio = pdev->initial_mmio_state; + int i, j; + + for (i = 0; i < num; i++, info++) { + if (!match_device(pdev, info)) + continue; + + for (j = 0; j < info->size; j += 4) + mmio[REG_INDEX(info->reg + j)] = + gvt_mmio_read(pdev, info->reg + j); + } + + gvt_dbg_core("save %d registers as initial mmio values", num); +} + +static void patch_display_mmio_state(u32 *mmio_array) +{ + gvt_dbg_core("patch display initial mmio state"); + + /* TODO: vgt_dpy_init_modes. */ + mmio_array[REG_INDEX(_WRPLL_CTL1)] &= ~(1 << 31); + mmio_array[REG_INDEX(_WRPLL_CTL2)] &= ~(1 << 31); +} + +static void patch_initial_mmio_state(struct pgt_device *pdev) +{ + u32 *mmio_array = pdev->initial_mmio_state; + + gvt_dbg_core("patch initial mmio state"); + + /* customize the initial MMIO + * 1, GMBUS status + * 2, Initial port status. + */ + + /* GMBUS2 has an in-use bit as the hw semaphore, and we should recover + * it after the snapshot. + */ + mmio_array[REG_INDEX(_PCH_GMBUS2)] &= ~0x8000; + + gvt_mmio_write(pdev, _PCH_GMBUS2, + gvt_mmio_read(pdev, _PCH_GMBUS2) | 0x8000); + + patch_display_mmio_state(mmio_array); +} + +void gvt_clean_initial_mmio_state(struct pgt_device *pdev) +{ + if (pdev->initial_mmio_state) { + vfree(pdev->initial_mmio_state); + pdev->initial_mmio_state = NULL; + } +} + +bool gvt_setup_initial_mmio_state(struct pgt_device *pdev) +{ + gvt_dbg_core("setup initial mmio state"); + + pdev->initial_mmio_state = vzalloc(pdev->mmio_size); + if (!pdev->initial_mmio_state) { + gvt_info("fail to allocate initial mmio state"); + return false; + } + + gvt_dbg_core("save generic initial mmio state"); + + save_initial_mmio_state(pdev, gvt_general_reg_info, gvt_get_reg_num(D_ALL)); + + if(IS_BROADWELL(pdev->dev_priv)) { + gvt_dbg_core("save broadwell initial mmio state"); + save_initial_mmio_state(pdev, gvt_broadwell_reg_info, gvt_get_reg_num(D_BDW)); + } + + patch_initial_mmio_state(pdev); + + return true; +} + +static void add_mmio_entry(struct pgt_device *pdev, struct gvt_mmio_entry *e) +{ + hash_add(pdev->mmio_table, &e->hlist, e->base); +} + +static struct gvt_mmio_entry *find_mmio_entry(struct pgt_device *pdev, unsigned int base) +{ + struct gvt_mmio_entry *e; + + hash_for_each_possible(pdev->mmio_table, e, hlist, base) { + if (base == e->base) + return e; + } + return NULL; +} + +void remove_mmio_entry(struct pgt_device *pdev, unsigned int base) +{ + struct gvt_mmio_entry *e; + + if ((e = find_mmio_entry(pdev, base))) { + hash_del(&e->hlist); + kfree(e); + } +} + +void free_mmio_table(struct pgt_device *pdev) +{ + struct hlist_node *tmp; + struct gvt_mmio_entry *e; + int i; + + hash_for_each_safe(pdev->mmio_table, i, tmp, e, hlist) + kfree(e); + + hash_init(pdev->mmio_table); +} + +bool register_mmio_handler(struct pgt_device *pdev, unsigned int start, int bytes, + gvt_mmio_handler_t read, gvt_mmio_handler_t write) +{ + unsigned int i, end; + struct gvt_mmio_entry *e; + + end = start + bytes -1; + + ASSERT((start & 3) == 0); + ASSERT(((end+1) & 3) == 0); + + for (i = start; i < end; i += 4) { + e = find_mmio_entry(pdev, i); + if (e) { + e->read = read; + e->write = write; + continue; + } + + e = kzalloc(sizeof(*e), GFP_KERNEL); + if (e == NULL) { + gvt_err("fail to allocate memory for mmio entry"); + return false; + } + + e->base = i; + + /* + * Win7 GFX driver uses memcpy to access the GVT PVINFO regs, + * hence align_bytes can be 1. + */ + if (start >= VGT_PVINFO_PAGE && + start < VGT_PVINFO_PAGE + VGT_PVINFO_SIZE) + e->align_bytes = 1; + else + e->align_bytes = 4; + + e->read = read; + e->write = write; + INIT_HLIST_NODE(&e->hlist); + add_mmio_entry(pdev, e); + } + return true; +} + +static void set_reg_attribute(struct pgt_device *pdev, + u32 reg, struct gvt_reg_info *info) +{ + /* ensure one entry per reg */ + ASSERT_NUM(!reg_is_tracked(pdev, reg), reg); + + if (reg_is_tracked(pdev, reg)) + return; + + if (info->flags & GVT_REG_ADDR_FIX) { + if (!info->addr_mask) + gvt_info("ZERO addr fix mask for %x", reg); + + reg_set_addr_fix(pdev, reg, info->addr_mask); + /* set the default range size to 4, might be updated later */ + reg_aux_addr_size(pdev, reg) = 4; + } + + if (info->flags & GVT_REG_MODE_CTL) + reg_set_mode_ctl(pdev, reg); + if (info->flags & GVT_REG_VIRT) + reg_set_virt(pdev, reg); + if (info->flags & GVT_REG_HW_STATUS) + reg_set_hw_status(pdev, reg); + + reg_set_tracked(pdev, reg); +} + +static bool setup_reg_info(struct pgt_device *pdev, struct gvt_reg_info *info, int num) +{ + int i, count = 0, total = 0; + u32 reg; + + for (i = 0; i < num; i++, info++) { + if (!match_device(pdev, info)) + continue; + + count++; + + for (reg = info->reg; + reg < info->reg + info->size; + reg += 4) { + set_reg_attribute(pdev, reg, info); + total++; + } + + if (info->read || info->write) + if (!register_mmio_handler(pdev, info->reg, info->size, + info->read, info->write)) + return false; + } + + gvt_info("total register tracked %d, total mmio entry %d", + count, total); + + return true; +} + +void gvt_clean_mmio_emulation_state(struct pgt_device *pdev) +{ + free_mmio_table(pdev); +} + +bool gvt_setup_mmio_emulation_state(struct pgt_device *pdev) +{ + struct gvt_mmio_entry *e; + + gvt_dbg_core("setup generic register info"); + + if (!setup_reg_info(pdev, gvt_general_reg_info, gvt_get_reg_num(D_ALL))) + goto err; + + if(IS_BROADWELL(pdev->dev_priv)) { + gvt_dbg_core("setup broadwell register info"); + + if (!setup_reg_info(pdev, gvt_broadwell_reg_info, gvt_get_reg_num(D_BDW))) + goto err; + } + + /* GDRST can be accessed by byte */ + e = find_mmio_entry(pdev, _GEN6_GDRST); + if (e) + e->align_bytes = 1; + + return true; +err: + gvt_clean_mmio_emulation_state(pdev); + return false; +} diff --git a/drivers/gpu/drm/i915/gvt/mmio.h b/drivers/gpu/drm/i915/gvt/mmio.h new file mode 100644 index 0000000..caca60f --- /dev/null +++ b/drivers/gpu/drm/i915/gvt/mmio.h @@ -0,0 +1,87 @@ +/* + * Copyright(c) 2011-2016 Intel Corporation. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _GVT_MMIO_H_ +#define _GVT_MMIO_H_ + +#include "i915_drv.h" + +/* reg contains address, requiring fix */ +#define GVT_REG_ADDR_FIX (1 << 5) +/* Status bit updated from HW */ +#define GVT_REG_HW_STATUS (1 << 6) +/* Virtualized */ +#define GVT_REG_VIRT (1 << 7) +/* Mode ctl registers with high 16 bits as the mask bits */ +#define GVT_REG_MODE_CTL (1 << 8) +/* This reg has been tracked in vgt_base_reg_info */ +#define GVT_REG_TRACKED (1 << 10) +/* This reg has been accessed by a VM */ +#define GVT_REG_ACCESSED (1 << 11) +/* This reg is saved/restored at context switch time */ +#define GVT_REG_SAVED (1 << 12) +/* Accessed through GPU commands */ +#define GVT_REG_CMD_ACCESS (1 << 14) +/* index into another auxillary table. Maximum 256 entries now */ +#define GVT_REG_INDEX_SHIFT 16 +#define GVT_REG_INDEX_MASK (0xFFFF << GVT_REG_INDEX_SHIFT) + +#define GVT_AUX_TABLE_NUM 256 + +/* suppose a reg won't set both bits */ +typedef union { + struct { + u32 mask; + } mode_ctl; + struct { + u32 mask; + uint32_t size; + } addr_fix; +} gvt_aux_entry_t; + +struct vgt_device; + +typedef bool (*gvt_mmio_handler_t)(struct vgt_device *, unsigned int, void *, unsigned int); + +struct gvt_mmio_entry { + struct hlist_node hlist; + unsigned int base; + unsigned int align_bytes; + gvt_mmio_handler_t read; + gvt_mmio_handler_t write; +}; + +struct gvt_reg_info { + u32 reg; + u32 size; + u32 flags; + u32 addr_mask; + u32 device; + gvt_mmio_handler_t read; + gvt_mmio_handler_t write; +}; + +extern struct gvt_reg_info gvt_general_reg_info[]; +extern struct gvt_reg_info gvt_broadwell_reg_info[]; +extern int gvt_get_reg_num(int type); +#endif diff --git a/drivers/gpu/drm/i915/gvt/reg.h b/drivers/gpu/drm/i915/gvt/reg.h index d363b74..5682e1c 100644 --- a/drivers/gpu/drm/i915/gvt/reg.h +++ b/drivers/gpu/drm/i915/gvt/reg.h @@ -31,4 +31,8 @@ #define GVT_REG_CFG_SPACE_BAR1 0x18 #define GVT_REG_CFG_SPACE_BAR2 0x20 +#define _PCH_GMBUS2 0xc5108 + +#define _GEN6_GDRST 0x941c + #endif -- 1.9.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx