#define REG_DR_DSPBSTRIDE 0x71188
#define REG_DR_PIPEBCONF 0x71008
-#define REG_DE_PIPEASRC 0x6001c
+#define REG_DR_PIPEASRC 0x6001c
+#define REG_DR_PIPEBSRC 0x6101c
extern int vga_passthrough;
uint32_t guest_framebuffer;
return *(unsigned int*)(intel_mmio + reg);
}
+static inline void intel_get_res(unsigned int *x, unsigned int *y)
+{
+ unsigned int *pipeaconf = (unsigned int *)(intel_mmio + REG_DR_PIPEACONF);
+ unsigned int *pipebconf = (unsigned int *)(intel_mmio + REG_DR_PIPEBCONF);
+
+ if ((*pipeaconf & (1 << 30)))
+ {
+ *x = ((intel_get_reg(REG_DR_PIPEASRC) >> 16) & 0xfff) + 1;
+ *y = (intel_get_reg(REG_DR_PIPEASRC) & 0xfff) + 1;
+ return;
+ }
+ if ((*pipebconf & (1 << 30)))
+ {
+ *x = ((intel_get_reg(REG_DR_PIPEBSRC) >> 16) & 0xfff) + 1;
+ *y = (intel_get_reg(REG_DR_PIPEBSRC) & 0xfff) + 1;
+ return;
+ }
+
+ INTEL_DEBUG("No pipe available (PIPEACONF=0x%x,PIPEBCONF=0x%x)!!\n",
+ *pipeaconf, *pipebconf);
+ exit(2);
+}
+
+static inline unsigned int get_surf(void)
+{
+ unsigned int *dspacntr = (unsigned int *)(intel_mmio + REG_DR_DSPACNTR);
+ unsigned int *dspbcntr = (unsigned int *)(intel_mmio + REG_DR_DSPBCNTR);
+
+ if ((*dspacntr & (1 << 31)))
+ return *(unsigned int *)(intel_mmio + REG_DR_DSPASURF);
+ if ((*dspbcntr & (1 << 31)))
+ return *(unsigned int *)(intel_mmio + REG_DR_DSPBSURF);
+
+ INTEL_DEBUG("No surface available (DSPACNTR=0x%x,DSPBCNTR=0x%x)!!\n",
+ *dspacntr, *dspbcntr);
+ exit(2);
+}
+
static inline int is_linear(void)
{
unsigned int *dspacntr = (unsigned int *)(intel_mmio + REG_DR_DSPACNTR);
- if (((*dspacntr) & (1 << 10)) == 0)
+ unsigned int *dspbcntr = (unsigned int *)(intel_mmio + REG_DR_DSPBCNTR);
+
+ if (((*dspacntr & (1 << 31)) && (*dspacntr & (1 << 10) == 0)) ||
+ ((*dspbcntr & (1 << 31)) && (*dspbcntr & (1 << 10)) == 0))
+ {
+ INTEL_DEBUG("Framebuffer is linear\n");
return 1;
+ }
else
return 0;
}
-static inline unsigned int intel_get_pitch(void)
+static inline void intel_get_pitch(DisplayState *ds)
{
- unsigned int *dspastride = (unsigned int *)(intel_mmio + REG_DR_DSPASTRIDE);
- return *dspastride;
+ unsigned int *dspacntr = (unsigned int *)(intel_mmio + REG_DR_DSPACNTR);
+ unsigned int *dspbcntr = (unsigned int *)(intel_mmio + REG_DR_DSPBCNTR);
+
+ if (*dspacntr != -1 && (*dspacntr & (1 << 31)))
+ {
+ ds->linesize = *(unsigned int *)(intel_mmio + REG_DR_DSPASTRIDE);
+ return;
+ }
+ if (*dspbcntr != -1 && (*dspbcntr & (1 << 31)))
+ {
+ ds->linesize = *(unsigned int *)(intel_mmio + REG_DR_DSPBSTRIDE);
+ return;
+ }
+
+ INTEL_DEBUG("No surface available (DSPACNTR=0x%x,DSPBCNTR=0x%x)!!\n",
+ *dspacntr, *dspbcntr);
+ ds->linesize = ds->width * (ds->depth / 8);
}
static inline unsigned int intel_get_offset(DisplayState *ds, int x, int y)
static void intel_update_linear(DisplayState *ds, int x, int y, int w, int h)
{
int i, bpp = lds->depth / 8;
- unsigned char *s, *d;
+ unsigned char *s, *d, *d2;
+
s = lds->data;
- d = (unsigned char *)(intel_mem + intel_get_reg(REG_DR_DSPASURF));
+ d = (unsigned char *)(intel_mem + get_surf());
s += (lds->linesize * y) + bpp * x;
d += (lds->linesize * y) + bpp * x;
for (i = 0; i < h; i++) {
unsigned int *dspbstride = (unsigned int *)(intel_mmio + REG_DR_DSPBSTRIDE);
unsigned int surfa, surfb, pipea, pipeb;
+ char pipeaenabled = !!(*pipeaconf & (1 << 30));
char pipebenabled = !!(*pipebconf & (1 << 30));
+ if (pipeaenabled)
+ {
+ INTEL_DEBUG("PIPEACONF enabled.\n");
- INTEL_DEBUG("DSPASURF CTRL: 0x%x\n", intel_get_reg(REG_DR_DSPACNTR));
-
- /* Disable surface */
- pipea = *pipeaconf & (0x3 << 18);
- *pipeaconf &= ~(0x3 << 18);
- *dspacntr |= (1 << 31);
- /* Address of the surface to map to */
- surfa = *dspasurf;
- *dspasurf = 0x00000000;
- *dspacntr &= ~(1 << 31);
- *dspasurf = 0x00000000;
- *pipeaconf |= pipea;
+ /* Disable surface */
+ pipea = *pipeaconf & (0x3 << 18);
+ *pipeaconf &= ~(0x3 << 18);
+ *dspacntr |= (1 << 31);
+ /* Address of the surface to map to */
+ surfa = *dspasurf;
+ *dspasurf = 0x00000000;
+ *dspacntr &= ~(1 << 31);
+ *dspasurf = 0x00000000;
+ *pipeaconf |= pipea;
+ }
if (pipebenabled) {
INTEL_DEBUG("PIPEBCONF enabled.\n");
usleep(20000);
- *pipeaconf &= ~(0x3 << 18);
- /* Enable surface linear mode */
- *dspacntr &= ~(1 << 10);
- if (linesize) *dspastride = linesize;
- *dspasurf = surfa;
- *dspacntr |= (1 << 31);
- *pipeaconf |= pipea;
+ if (pipeaenabled)
+ {
+ *pipeaconf &= ~(0x3 << 18);
+ /* Enable surface linear mode */
+ *dspacntr &= ~(1 << 10);
+ if (linesize) *dspastride = linesize;
+ *dspasurf = surfa;
+ *dspacntr |= (1 << 31);
+ *pipeaconf |= pipea;
+ }
if (pipebenabled) {
*pipebconf &= ~(0x3 << 18);
unsigned long nr_pfn;
unset_vga_acc();
- fprintf(stderr, "set_fb_mapping: %x %x\n", (intel_fb_base + intel_get_reg(REG_DR_DSPASURF)), guest_framebuffer);
+ fprintf(stderr, "set_fb_mapping: %x %x\n", (intel_fb_base + get_surf()), guest_framebuffer);
nr_pfn = (lds->linesize * lds->height) >> TARGET_PAGE_BITS;
rc = xc_domain_memory_mapping(xc_handle,
domid,
(guest_framebuffer >> TARGET_PAGE_BITS),
- ((intel_fb_base + intel_get_reg(REG_DR_DSPASURF)) >> TARGET_PAGE_BITS),
+ ((intel_fb_base + get_surf()) >> TARGET_PAGE_BITS),
nr_pfn,
DPCI_ADD_MAPPING);
if (rc) {
fprintf(stderr, "xc_domain_memory_mapping failed %d\n", rc);
return;
}
- map_s = ((intel_fb_base + intel_get_reg(REG_DR_DSPASURF)) >> TARGET_PAGE_BITS);
+ map_s = ((intel_fb_base + get_surf()) >> TARGET_PAGE_BITS);
map_d = (guest_framebuffer >> TARGET_PAGE_BITS);
map_size = nr_pfn;
}
static void intel_resize(DisplayState *ds, int w, int h)
{
- int old_linesize = ds->linesize;
- INTEL_DEBUG("intel_resize: no shared buffer, linesize=%d\n", ds->linesize);
+ int old_linesize;
+
+ INTEL_DEBUG("intel_resize: no shared buffer, w=%d,h=%d,linesize=%d\n",
+ w, h, ds->linesize);
+ old_linesize = ds->linesize;
ds->width = w;
ds->height = h;
ds->depth = 32;
- ds->linesize = intel_get_pitch();
+ intel_get_pitch(ds);
if (map_size) {
unset_fb_mapping();
unset_data_mappings(1);
set_data_pointer();
}
if (intel_have_focus)
- memset((unsigned char *)(intel_mem + intel_get_reg(REG_DR_DSPASURF)), 0x0, IntelX * IntelY);
+ memset((unsigned char *)(intel_mem + get_surf()), 0x0, IntelX * IntelY);
if (refresh) {
if (old_data) {
unsigned char *s, *d;
}
refresh = 0;
}
+ INTEL_DEBUG("intel_resize: done, w=%d,h=%d,linesize=%d\n",
+ ds->width, ds->height, ds->linesize);
}
static void intel_refresh(DisplayState *ds)
static void set_data_pointer(void)
{
- lds->data = (unsigned char *)(intel_mem + intel_get_reg(REG_DR_DSPASURF));
+ lds->data = (unsigned char *)(intel_mem + get_surf());
lds->data = lds->data +
lds->linesize * ((IntelY - lds->height) / 2) +
4 * ((IntelX - lds->width) / 2);
old_data = NULL;
lds->data = realloc(lds->data, lds->linesize * lds->height);
memcpy(lds->data,
- (unsigned char *)(intel_mem + intel_get_reg(REG_DR_DSPASURF)),
+ (unsigned char *)(intel_mem + get_surf()),
lds->linesize * lds->height);
memcpy(buffer_pointer,
lds->data,
if (focus) {
if (!is_linear()) {
IntelPitch = intel_get_reg(REG_DR_DSPASTRIDE);
- IntelX = ((intel_get_reg(REG_DE_PIPEASRC) >> 16) & 0xfff) + 1;
- IntelY = (intel_get_reg(REG_DE_PIPEASRC) & 0xfff) + 1;
+ intel_get_res(&IntelX, &IntelY);
INTEL_DEBUG("Resolution is %dx%d\n", IntelX, IntelY);
}
refresh = 1;
{
INTEL_DEBUG("\n");
- xenstore_watch_screenshot_node();
-
intel_init_mapping();
- INTEL_DEBUG("Frambuffer is at 0x%x\n", intel_get_reg(REG_DR_DSPASURF));
-
ds->shared_buf = 0;
intel_resize(ds, 640, 480);
lds = ds;