aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/hvm/stdvga.c
diff options
context:
space:
mode:
authorKeir Fraser <keir@xensource.com>2007-10-29 09:17:38 +0000
committerKeir Fraser <keir@xensource.com>2007-10-29 09:17:38 +0000
commit8ee4d89b7260fe7a4a5ba334146707715b4dca3c (patch)
tree951a9a321b5d8846ddf76631f56cc22244bee96b /xen/arch/x86/hvm/stdvga.c
parent20e7b4098f625f874158b0e166f2f9db9d043c5a (diff)
downloadxen-8ee4d89b7260fe7a4a5ba334146707715b4dca3c.tar.gz
xen-8ee4d89b7260fe7a4a5ba334146707715b4dca3c.tar.bz2
xen-8ee4d89b7260fe7a4a5ba334146707715b4dca3c.zip
x86, hvm: Clean up code style in stdvga code and do not compile for
32-bit hypervisor (it doesn't work). Signed-off-by: Keir Fraser <keir@xensource.com>
Diffstat (limited to 'xen/arch/x86/hvm/stdvga.c')
-rw-r--r--xen/arch/x86/hvm/stdvga.c323
1 files changed, 154 insertions, 169 deletions
diff --git a/xen/arch/x86/hvm/stdvga.c b/xen/arch/x86/hvm/stdvga.c
index d0cc4de6f3..79bcc5b074 100644
--- a/xen/arch/x86/hvm/stdvga.c
+++ b/xen/arch/x86/hvm/stdvga.c
@@ -7,8 +7,6 @@
* License, version 2.1 and not any later version of the GPL, as published
* by the Free Software Foundation.
*
- *
- *
* This improves the performance of Standard VGA,
* the mode used during Windows boot and by the Linux
* splash screen.
@@ -24,7 +22,7 @@
* PIO input ops are satisfied from cached state without
* bothering QEMU.
*
- PIO output and mmio ops are passed through to QEMU, including
+ * PIO output and mmio ops are passed through to QEMU, including
* mmio read ops. This is necessary because mmio reads
* can have side effects.
*/
@@ -34,15 +32,12 @@
#include <xen/sched.h>
#include <asm/hvm/support.h>
-#define vram_b(_s, _a) (((uint8_t*) (_s)->vram_ptr[((_a)>>12)&0x3f])[(_a)&0xfff])
-#define vram_w(_s, _a) (((uint16_t*)(_s)->vram_ptr[((_a)>>11)&0x3f])[(_a)&0x7ff])
-#define vram_l(_s, _a) (((uint32_t*)(_s)->vram_ptr[((_a)>>10)&0x3f])[(_a)&0x3ff])
-
-#ifdef STDVGA_STATS
-#define UPDATE_STATS(x) x
-#else
-#define UPDATE_STATS(x)
-#endif
+#define vram_b(_s, _a) \
+ (((uint8_t*) (_s)->vram_ptr[((_a)>>12)&0x3f])[(_a)&0xfff])
+#define vram_w(_s, _a) \
+ (((uint16_t*)(_s)->vram_ptr[((_a)>>11)&0x3f])[(_a)&0x7ff])
+#define vram_l(_s, _a) \
+ (((uint32_t*)(_s)->vram_ptr[((_a)>>10)&0x3f])[(_a)&0x3ff])
#define PAT(x) (x)
static const uint32_t mask16[16] = {
@@ -92,13 +87,15 @@ static uint64_t stdvga_inb(uint64_t addr)
{
struct hvm_hw_stdvga *s = &current->domain->arch.hvm_domain.stdvga;
uint8_t val = 0;
- switch (addr) {
+
+ switch ( addr )
+ {
case 0x3c4: /* sequencer address register */
val = s->sr_index;
break;
case 0x3c5: /* sequencer data register */
- if (s->sr_index < sizeof(s->sr))
+ if ( s->sr_index < sizeof(s->sr) )
val = s->sr[s->sr_index];
break;
@@ -113,6 +110,7 @@ static uint64_t stdvga_inb(uint64_t addr)
default:
gdprintk(XENLOG_WARNING, "unexpected io addr 0x%04x\n", (int)addr);
}
+
return val;
}
@@ -120,7 +118,9 @@ static uint64_t stdvga_in(ioreq_t *p)
{
/* Satisfy reads from sequence and graphics registers using local values */
uint64_t data = 0;
- switch (p->size) {
+
+ switch ( p->size )
+ {
case 1:
data = stdvga_inb(p->addr);
break;
@@ -151,6 +151,7 @@ static uint64_t stdvga_in(ioreq_t *p)
default:
gdprintk(XENLOG_WARNING, "invalid io size:%d\n", (int)p->size);
}
+
return data;
}
@@ -161,13 +162,15 @@ static void stdvga_outb(uint64_t addr, uint8_t val)
struct hvm_hw_stdvga *s = &current->domain->arch.hvm_domain.stdvga;
int prev_stdvga = s->stdvga;
- switch (addr) {
+ switch ( addr )
+ {
case 0x3c4: /* sequencer address register */
s->sr_index = val;
break;
case 0x3c5: /* sequencer data register */
- switch (s->sr_index) {
+ switch ( s->sr_index )
+ {
case 0x00 ... 0x05:
case 0x07:
s->sr[s->sr_index] = val & sr_mask[s->sr_index];
@@ -176,7 +179,7 @@ static void stdvga_outb(uint64_t addr, uint8_t val)
s->sr[s->sr_index] = ((val & 0x17) == 0x12) ? 0x12 : 0x0f;
break;
default:
- if (s->sr_index < sizeof(s->sr))
+ if ( s->sr_index < sizeof(s->sr) )
s->sr[s->sr_index] = val;
break;
}
@@ -187,37 +190,43 @@ static void stdvga_outb(uint64_t addr, uint8_t val)
break;
case 0x3cf: /* graphics data register */
- if (s->gr_index < sizeof(gr_mask)) {
+ if ( s->gr_index < sizeof(gr_mask) )
+ {
s->gr[s->gr_index] = val & gr_mask[s->gr_index];
}
- else if (s->gr_index == 0xff && s->vram_ptr != NULL) {
+ else if ( (s->gr_index == 0xff) && (s->vram_ptr != NULL) )
+ {
uint32_t addr;
- for (addr = 0xa0000; addr < 0xa4000; addr += 2)
+ for ( addr = 0xa0000; addr < 0xa4000; addr += 2 )
vram_w(s, addr) = (val << 8) | s->gr[0xfe];
}
else
+ {
s->gr[s->gr_index] = val;
+ }
break;
}
/* When in standard vga mode, emulate here all writes to the vram buffer
* so we can immediately satisfy reads without waiting for qemu. */
s->stdvga =
- s->sr[0x07] == 0 && /* standard vga mode */
- s->gr[6] == 0x05; /* misc graphics register w/ MemoryMapSelect=1 0xa0000-0xaffff (64K region) and AlphaDis=1 */
+ (s->sr[0x07] == 0) && /* standard vga mode */
+ (s->gr[6] == 0x05); /* misc graphics register w/ MemoryMapSelect=1
+ * 0xa0000-0xaffff (64k region), AlphaDis=1 */
- if (!prev_stdvga && s->stdvga) {
+ if ( !prev_stdvga && s->stdvga )
+ {
s->cache = 1; /* (re)start caching video buffer */
gdprintk(XENLOG_INFO, "entering stdvga and caching modes\n");
}
- else
- if (prev_stdvga && !s->stdvga)
- gdprintk(XENLOG_INFO, "leaving stdvga\n");
+ else if ( prev_stdvga && !s->stdvga )
+ gdprintk(XENLOG_INFO, "leaving stdvga\n");
}
static void stdvga_outv(uint64_t addr, uint64_t data, uint32_t size)
{
- switch (size) {
+ switch ( size )
+ {
case 1:
stdvga_outb(addr, data);
break;
@@ -252,10 +261,12 @@ static void stdvga_outv(uint64_t addr, uint64_t data, uint32_t size)
static void stdvga_out(ioreq_t *p)
{
- if (p->data_is_ptr) {
+ if ( p->data_is_ptr )
+ {
int i, sign = p->df ? -1 : 1;
uint64_t addr = p->addr, data = p->data, tmp;
- for (i = 0; i < p->count; i++) {
+ for ( i = 0; i < p->count; i++ )
+ {
hvm_copy_from_guest_phys(&tmp, data, p->size);
stdvga_outv(addr, tmp, p->size);
data += sign * p->size;
@@ -263,45 +274,46 @@ static void stdvga_out(ioreq_t *p)
}
}
else
+ {
stdvga_outv(p->addr, p->data, p->size);
+ }
}
int stdvga_intercept_pio(ioreq_t *p)
{
struct hvm_hw_stdvga *s = &current->domain->arch.hvm_domain.stdvga;
- int buf = 0;
+ int buf = 0, rc;
- if (p->size > 8) {
+ if ( p->size > 8 )
+ {
gdprintk(XENLOG_WARNING, "stdvga bad access size %d\n", (int)p->size);
return 0;
}
spin_lock(&s->lock);
- if ( p->dir == IOREQ_READ ) {
- if (p->size != 1)
+
+ if ( p->dir == IOREQ_READ )
+ {
+ if ( p->size != 1 )
gdprintk(XENLOG_WARNING, "unexpected io size:%d\n", (int)p->size);
- if (!(p->addr == 0x3c5 && s->sr_index >= sizeof(sr_mask)) &&
- !(p->addr == 0x3cf && s->gr_index >= sizeof(gr_mask)))
+ if ( !((p->addr == 0x3c5) && (s->sr_index >= sizeof(sr_mask))) &&
+ !((p->addr == 0x3cf) && (s->gr_index >= sizeof(gr_mask))) )
{
p->data = stdvga_in(p);
buf = 1;
}
}
- else {
+ else
+ {
stdvga_out(p);
buf = 1;
}
- if (buf && hvm_buffered_io_send(p)) {
- UPDATE_STATS(s->stats.nr_pio_buffered_wr++);
- spin_unlock(&s->lock);
- return 1;
- }
- else {
- UPDATE_STATS(s->stats.nr_pio_unbuffered_wr++);
- spin_unlock(&s->lock);
- return 0;
- }
+ rc = (buf && hvm_buffered_io_send(p));
+
+ spin_unlock(&s->lock);
+
+ return rc;
}
#define GET_PLANE(data, p) (((data) >> ((p) * 8)) & 0xff)
@@ -313,25 +325,33 @@ static uint8_t stdvga_mem_readb(uint64_t addr)
uint32_t ret;
addr &= 0x1ffff;
- if (addr >= 0x10000)
+ if ( addr >= 0x10000 )
return 0xff;
- if (s->sr[4] & 0x08) {
+ if ( s->sr[4] & 0x08 )
+ {
/* chain 4 mode : simplest access */
ret = vram_b(s, addr);
- } else if (s->gr[5] & 0x10) {
+ }
+ else if ( s->gr[5] & 0x10 )
+ {
/* odd/even mode (aka text mode mapping) */
plane = (s->gr[4] & 2) | (addr & 1);
ret = vram_b(s, ((addr & ~1) << 1) | plane);
- } else {
+ }
+ else
+ {
/* standard VGA latched access */
s->latch = vram_l(s, addr);
- if (!(s->gr[5] & 0x08)) {
+ if ( !(s->gr[5] & 0x08) )
+ {
/* read mode 0 */
plane = s->gr[4];
ret = GET_PLANE(s->latch, plane);
- } else {
+ }
+ else
+ {
/* read mode 1 */
ret = (s->latch ^ mask16[s->gr[2]]) & mask16[s->gr[7]];
ret |= ret >> 16;
@@ -339,6 +359,7 @@ static uint8_t stdvga_mem_readb(uint64_t addr)
ret = (~ret) & 0xff;
}
}
+
return ret;
}
@@ -346,7 +367,8 @@ static uint32_t stdvga_mem_read(uint32_t addr, uint32_t size)
{
uint32_t data = 0;
- switch (size) {
+ switch ( size )
+ {
case 1:
data = stdvga_mem_readb(addr);
break;
@@ -365,7 +387,9 @@ static uint32_t stdvga_mem_read(uint32_t addr, uint32_t size)
default:
gdprintk(XENLOG_WARNING, "invalid io size:%d\n", size);
+ break;
}
+
return data;
}
@@ -376,27 +400,32 @@ static void stdvga_mem_writeb(uint64_t addr, uint32_t val)
uint32_t write_mask, bit_mask, set_mask;
addr &= 0x1ffff;
- if (addr >= 0x10000)
+ if ( addr >= 0x10000 )
return;
- if (s->sr[4] & 0x08) {
+ if ( s->sr[4] & 0x08 )
+ {
/* chain 4 mode : simplest access */
plane = addr & 3;
mask = (1 << plane);
- if (s->sr[2] & mask) {
+ if ( s->sr[2] & mask )
vram_b(s, addr) = val;
- }
- } else if (s->gr[5] & 0x10) {
+ } else if ( s->gr[5] & 0x10 )
+ {
/* odd/even mode (aka text mode mapping) */
plane = (s->gr[4] & 2) | (addr & 1);
mask = (1 << plane);
- if (s->sr[2] & mask) {
+ if ( s->sr[2] & mask )
+ {
addr = ((addr & ~1) << 1) | plane;
vram_b(s, addr) = val;
}
- } else {
+ }
+ else
+ {
write_mode = s->gr[5] & 3;
- switch(write_mode) {
+ switch ( write_mode )
+ {
default:
case 0:
/* rotate */
@@ -429,7 +458,8 @@ static void stdvga_mem_writeb(uint64_t addr, uint32_t val)
/* apply logical operation */
func_select = s->gr[3] >> 3;
- switch(func_select) {
+ switch ( func_select )
+ {
case 0:
default:
/* nothing to do */
@@ -466,7 +496,8 @@ static void stdvga_mem_writeb(uint64_t addr, uint32_t val)
static void stdvga_mem_write(uint32_t addr, uint32_t data, uint32_t size)
{
/* Intercept mmio write */
- switch (size) {
+ switch ( size )
+ {
case 1:
stdvga_mem_writeb(addr, (data >> 0) & 0xff);
break;
@@ -485,6 +516,7 @@ static void stdvga_mem_write(uint32_t addr, uint32_t data, uint32_t size)
default:
gdprintk(XENLOG_WARNING, "invalid io size:%d\n", size);
+ break;
}
}
@@ -495,19 +527,24 @@ static int mmio_move(struct hvm_hw_stdvga *s, ioreq_t *p)
int i;
int sign = p->df ? -1 : 1;
- if (p->data_is_ptr) {
- if (p->dir == IOREQ_READ ) {
+ if ( p->data_is_ptr )
+ {
+ if ( p->dir == IOREQ_READ )
+ {
uint32_t addr = p->addr, data = p->data, tmp;
- for (i = 0; i < p->count; i++) {
+ for ( i = 0; i < p->count; i++ )
+ {
tmp = stdvga_mem_read(addr, p->size);
hvm_copy_to_guest_phys(data, &tmp, p->size);
data += sign * p->size;
addr += sign * p->size;
}
}
- else {
+ else
+ {
uint32_t addr = p->addr, data = p->data, tmp;
- for (i = 0; i < p->count; i++) {
+ for ( i = 0; i < p->count; i++ )
+ {
hvm_copy_from_guest_phys(&tmp, data, p->size);
stdvga_mem_write(addr, tmp, p->size);
data += sign * p->size;
@@ -515,17 +552,22 @@ static int mmio_move(struct hvm_hw_stdvga *s, ioreq_t *p)
}
}
}
- else {
- if (p->dir == IOREQ_READ ) {
+ else
+ {
+ if ( p->dir == IOREQ_READ )
+ {
uint32_t addr = p->addr;
- for (i = 0; i < p->count; i++) {
+ for ( i = 0; i < p->count; i++ )
+ {
p->data = stdvga_mem_read(addr, p->size);
addr += sign * p->size;
}
}
- else {
+ else
+ {
uint32_t addr = p->addr;
- for (i = 0; i < p->count; i++) {
+ for ( i = 0; i < p->count; i++ )
+ {
stdvga_mem_write(addr, p->data, p->size);
addr += sign * p->size;
}
@@ -553,11 +595,13 @@ static int mmio_op(struct hvm_hw_stdvga *s, ioreq_t *p)
{
uint32_t orig, mod = 0;
orig = stdvga_mem_read(p->addr, p->size);
- if (p->dir == IOREQ_WRITE) {
+
+ if ( p->dir == IOREQ_WRITE )
+ {
mod = (op_array[p->type])(orig, p->data);
stdvga_mem_write(p->addr, mod, p->size);
}
- // p->data = orig; // Can't modify p->data yet. QEMU still needs to use it. So return zero below.
+
return 0; /* Don't try to buffer these operations */
}
@@ -565,17 +609,20 @@ int stdvga_intercept_mmio(ioreq_t *p)
{
struct domain *d = current->domain;
struct hvm_hw_stdvga *s = &d->arch.hvm_domain.stdvga;
- int buf = 0;
+ int buf = 0, rc;
- if (p->size > 8) {
+ if ( p->size > 8 )
+ {
gdprintk(XENLOG_WARNING, "invalid mmio size %d\n", (int)p->size);
return 0;
}
spin_lock(&s->lock);
- if (s->stdvga && s->cache) {
- switch (p->type) {
+ if ( s->stdvga && s->cache )
+ {
+ switch ( p->type )
+ {
case IOREQ_TYPE_COPY:
buf = mmio_move(s, p);
break;
@@ -588,23 +635,20 @@ int stdvga_intercept_mmio(ioreq_t *p)
break;
default:
gdprintk(XENLOG_ERR, "unsupported mmio request type:%d "
- "addr:0x%04x data:0x%04x size:%d count:%d state:%d isptr:%d dir:%d df:%d\n",
- p->type,
- (int)p->addr, (int)p->data, (int)p->size, (int)p->count, p->state,
+ "addr:0x%04x data:0x%04x size:%d count:%d state:%d "
+ "isptr:%d dir:%d df:%d\n",
+ p->type, (int)p->addr, (int)p->data, (int)p->size,
+ (int)p->count, p->state,
p->data_is_ptr, p->dir, p->df);
s->cache = 0;
}
}
- if (buf && hvm_buffered_io_send(p)) {
- UPDATE_STATS(p->dir == IOREQ_READ ? s->stats.nr_mmio_buffered_rd++ : s->stats.nr_mmio_buffered_wr++);
- spin_unlock(&s->lock);
- return 1;
- }
- else {
- UPDATE_STATS(p->dir == IOREQ_READ ? s->stats.nr_mmio_unbuffered_rd++ : s->stats.nr_mmio_unbuffered_wr++);
- spin_unlock(&s->lock);
- return 0;
- }
+
+ rc = (buf && hvm_buffered_io_send(p));
+
+ spin_unlock(&s->lock);
+
+ return rc;
}
void stdvga_init(struct domain *d)
@@ -614,18 +658,25 @@ void stdvga_init(struct domain *d)
memset(s, 0, sizeof(*s));
spin_lock_init(&s->lock);
- for (i = 0; i != ARRAY_SIZE(s->vram_ptr); i++) {
+ for ( i = 0; i != ARRAY_SIZE(s->vram_ptr); i++ )
+ {
struct page_info *vram_page;
vram_page = alloc_domheap_page(NULL);
- if (!vram_page)
+ if ( vram_page == NULL )
break;
s->vram_ptr[i] = page_to_virt(vram_page);
memset(s->vram_ptr[i], 0, PAGE_SIZE);
}
- if (i == ARRAY_SIZE(s->vram_ptr)) {
- register_portio_handler(d, 0x3c4, 2, stdvga_intercept_pio); /* sequencer registers */
- register_portio_handler(d, 0x3ce, 2, stdvga_intercept_pio); /* graphics registers */
- register_buffered_io_handler(d, 0xa0000, 0x10000, stdvga_intercept_mmio); /* mmio */
+
+ if ( i == ARRAY_SIZE(s->vram_ptr) )
+ {
+ /* Sequencer registers. */
+ register_portio_handler(d, 0x3c4, 2, stdvga_intercept_pio);
+ /* Graphics registers. */
+ register_portio_handler(d, 0x3ce, 2, stdvga_intercept_pio);
+ /* MMIO. */
+ register_buffered_io_handler(d, 0xa0000, 0x10000,
+ stdvga_intercept_mmio);
}
}
@@ -633,80 +684,14 @@ void stdvga_deinit(struct domain *d)
{
struct hvm_hw_stdvga *s = &d->arch.hvm_domain.stdvga;
int i;
- for (i = 0; i != ARRAY_SIZE(s->vram_ptr); i++) {
+
+ for ( i = 0; i != ARRAY_SIZE(s->vram_ptr); i++ )
+ {
struct page_info *vram_page;
- if (s->vram_ptr[i] == NULL)
+ if ( s->vram_ptr[i] == NULL )
continue;
vram_page = virt_to_page(s->vram_ptr[i]);
free_domheap_page(vram_page);
s->vram_ptr[i] = NULL;
}
}
-
-#ifdef STDVGA_STATS
-static void stdvga_stats_dump(unsigned char key)
-{
- struct domain *d;
-
- printk("%s: key '%c' pressed\n", __FUNCTION__, key);
-
- rcu_read_lock(&domlist_read_lock);
-
- for_each_domain ( d )
- {
- struct hvm_hw_stdvga *s;
- int i;
-
- if ( !is_hvm_domain(d) )
- continue;
-
- s = &d->arch.hvm_domain.stdvga;
- spin_lock(&s->lock);
- printk("\n>>> Domain %d <<<\n", d->domain_id);
- printk(" modes: stdvga:%d caching:%d\n", s->stdvga, s->cache);
- printk(" %8s %8s\n", "read", "write");
- printk(" nr_mmio_buffered: %8u %8u\n", s->stats.nr_mmio_buffered_rd, s->stats.nr_mmio_buffered_wr);
- printk(" nr_mmio_unbuffered:%8u %8u\n", s->stats.nr_mmio_unbuffered_rd, s->stats.nr_mmio_unbuffered_wr);
- printk(" nr_pio_buffered: %8u %8u\n", s->stats.nr_pio_buffered_rd, s->stats.nr_pio_buffered_wr);
- printk(" nr_pio_unbuffered: %8u %8u\n", s->stats.nr_pio_unbuffered_rd, s->stats.nr_pio_unbuffered_wr);
-
- for (i = 0; i != sizeof(s->sr); i++) {
- if (i % 8 == 0)
- printk(" sr[0x%02x] ", i);
- printk("%02x ", s->sr[i]);
- if (i % 8 == 7)
- printk("\n");
- }
- if (i % 8 != 7)
- printk("\n");
-
- for (i = 0; i != sizeof(s->gr); i++) {
- if (i % 8 == 0)
- printk(" gr[0x%02x] ", i);
- printk("%02x ", s->gr[i]);
- if (i % 8 == 7)
- printk("\n");
- }
- if (i % 8 != 7)
- printk("\n");
-
- memset(&s->stats, 0, sizeof(s->stats));
-
- spin_unlock(&s->lock);
- }
-
- rcu_read_unlock(&domlist_read_lock);
-}
-
-#include <xen/keyhandler.h>
-
-static int __init setup_stdvga_stats_dump(void)
-{
- register_keyhandler('<', stdvga_stats_dump, "dump stdvga stats");
- return 0;
-}
-
-__initcall(setup_stdvga_stats_dump);
-
-#endif
-