ia64/xen-unstable

changeset 16381:d1ac500f77c1

x86, hvm: Allow stdvga acceleration to work with 32-bit x86.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Nov 16 14:40:22 2007 +0000 (2007-11-16)
parents 01d5511e47ba
children 79d050b2b35e
files xen/arch/x86/hvm/Makefile xen/arch/x86/hvm/stdvga.c xen/include/asm-x86/hvm/io.h
line diff
     1.1 --- a/xen/arch/x86/hvm/Makefile	Thu Nov 15 22:14:13 2007 +0000
     1.2 +++ b/xen/arch/x86/hvm/Makefile	Fri Nov 16 14:40:22 2007 +0000
     1.3 @@ -17,5 +17,4 @@ obj-y += vioapic.o
     1.4  obj-y += vlapic.o
     1.5  obj-y += vpic.o
     1.6  obj-y += save.o
     1.7 -
     1.8 -obj-$(x86_64) += stdvga.o
     1.9 +obj-y += stdvga.o
     2.1 --- a/xen/arch/x86/hvm/stdvga.c	Thu Nov 15 22:14:13 2007 +0000
     2.2 +++ b/xen/arch/x86/hvm/stdvga.c	Fri Nov 16 14:40:22 2007 +0000
     2.3 @@ -30,15 +30,9 @@
     2.4  #include <xen/config.h>
     2.5  #include <xen/types.h>
     2.6  #include <xen/sched.h>
     2.7 +#include <xen/domain_page.h>
     2.8  #include <asm/hvm/support.h>
     2.9  
    2.10 -#define vram_b(_s, _a) \
    2.11 -    (((uint8_t*) (_s)->vram_ptr[((_a)>>12)&0x3f])[(_a)&0xfff])
    2.12 -#define vram_w(_s, _a) \
    2.13 -    (((uint16_t*)(_s)->vram_ptr[((_a)>>11)&0x3f])[(_a)&0x7ff])
    2.14 -#define vram_l(_s, _a) \
    2.15 -    (((uint32_t*)(_s)->vram_ptr[((_a)>>10)&0x3f])[(_a)&0x3ff])
    2.16 -
    2.17  #define PAT(x) (x)
    2.18  static const uint32_t mask16[16] = {
    2.19      PAT(0x00000000),
    2.20 @@ -83,6 +77,25 @@ const uint8_t gr_mask[16] = {
    2.21      (uint8_t)~0x00, /* 0x08 */
    2.22  };
    2.23  
    2.24 +static uint8_t *vram_getb(struct hvm_hw_stdvga *s, unsigned int a)
    2.25 +{
    2.26 +    struct page_info *pg = s->vram_page[(a >> 12) & 0x3f];
    2.27 +    uint8_t *p = map_domain_page(page_to_mfn(pg));
    2.28 +    return &p[a & 0xfff];
    2.29 +}
    2.30 +
    2.31 +static uint32_t *vram_getl(struct hvm_hw_stdvga *s, unsigned int a)
    2.32 +{
    2.33 +    struct page_info *pg = s->vram_page[(a >> 10) & 0x3f];
    2.34 +    uint32_t *p = map_domain_page(page_to_mfn(pg));
    2.35 +    return &p[a & 0x3ff];
    2.36 +}
    2.37 +
    2.38 +static void vram_put(struct hvm_hw_stdvga *s, void *p)
    2.39 +{
    2.40 +    unmap_domain_page(p);
    2.41 +}
    2.42 +
    2.43  static uint64_t stdvga_inb(uint64_t addr)
    2.44  {
    2.45      struct hvm_hw_stdvga *s = &current->domain->arch.hvm_domain.stdvga;
    2.46 @@ -190,20 +203,9 @@ static void stdvga_outb(uint64_t addr, u
    2.47          break;
    2.48  
    2.49      case 0x3cf:                 /* graphics data register */
    2.50 +        s->gr[s->gr_index] = val;
    2.51          if ( s->gr_index < sizeof(gr_mask) )
    2.52 -        {
    2.53 -            s->gr[s->gr_index] = val & gr_mask[s->gr_index];
    2.54 -        }
    2.55 -        else if ( (s->gr_index == 0xff) && (s->vram_ptr != NULL) )
    2.56 -        {
    2.57 -            uint32_t addr;
    2.58 -            for ( addr = 0xa0000; addr < 0xa4000; addr += 2 )
    2.59 -                vram_w(s, addr) = (val << 8) | s->gr[0xfe];
    2.60 -        }
    2.61 -        else
    2.62 -        {
    2.63 -            s->gr[s->gr_index] = val;
    2.64 -        }
    2.65 +            s->gr[s->gr_index] &= gr_mask[s->gr_index];
    2.66          break;
    2.67      }
    2.68  
    2.69 @@ -326,7 +328,8 @@ static uint8_t stdvga_mem_readb(uint64_t
    2.70  {
    2.71      struct hvm_hw_stdvga *s = &current->domain->arch.hvm_domain.stdvga;
    2.72      int plane;
    2.73 -    uint32_t ret;
    2.74 +    uint32_t ret, *vram_l;
    2.75 +    uint8_t *vram_b;
    2.76  
    2.77      addr &= 0x1ffff;
    2.78      if ( addr >= 0x10000 )
    2.79 @@ -335,18 +338,24 @@ static uint8_t stdvga_mem_readb(uint64_t
    2.80      if ( s->sr[4] & 0x08 )
    2.81      {
    2.82          /* chain 4 mode : simplest access */
    2.83 -        ret = vram_b(s, addr);
    2.84 +        vram_b = vram_getb(s, addr);
    2.85 +        ret = *vram_b;
    2.86 +        vram_put(s, vram_b);
    2.87      }
    2.88      else if ( s->gr[5] & 0x10 )
    2.89      {
    2.90          /* odd/even mode (aka text mode mapping) */
    2.91          plane = (s->gr[4] & 2) | (addr & 1);
    2.92 -        ret = vram_b(s, ((addr & ~1) << 1) | plane);
    2.93 +        vram_b = vram_getb(s, ((addr & ~1) << 1) | plane);
    2.94 +        ret = *vram_b;
    2.95 +        vram_put(s, vram_b);
    2.96      }
    2.97      else
    2.98      {
    2.99          /* standard VGA latched access */
   2.100 -        s->latch = vram_l(s, addr);
   2.101 +        vram_l = vram_getl(s, addr);
   2.102 +        s->latch = *vram_l;
   2.103 +        vram_put(s, vram_l);
   2.104  
   2.105          if ( !(s->gr[5] & 0x08) )
   2.106          {
   2.107 @@ -401,7 +410,8 @@ static void stdvga_mem_writeb(uint64_t a
   2.108  {
   2.109      struct hvm_hw_stdvga *s = &current->domain->arch.hvm_domain.stdvga;
   2.110      int plane, write_mode, b, func_select, mask;
   2.111 -    uint32_t write_mask, bit_mask, set_mask;
   2.112 +    uint32_t write_mask, bit_mask, set_mask, *vram_l;
   2.113 +    uint8_t *vram_b;
   2.114  
   2.115      addr &= 0x1ffff;
   2.116      if ( addr >= 0x10000 )
   2.117 @@ -413,8 +423,13 @@ static void stdvga_mem_writeb(uint64_t a
   2.118          plane = addr & 3;
   2.119          mask = (1 << plane);
   2.120          if ( s->sr[2] & mask )
   2.121 -            vram_b(s, addr) = val;
   2.122 -    } else if ( s->gr[5] & 0x10 )
   2.123 +        {
   2.124 +            vram_b = vram_getb(s, addr);
   2.125 +            *vram_b = val;
   2.126 +            vram_put(s, vram_b);
   2.127 +        }
   2.128 +    }
   2.129 +    else if ( s->gr[5] & 0x10 )
   2.130      {
   2.131          /* odd/even mode (aka text mode mapping) */
   2.132          plane = (s->gr[4] & 2) | (addr & 1);
   2.133 @@ -422,7 +437,9 @@ static void stdvga_mem_writeb(uint64_t a
   2.134          if ( s->sr[2] & mask )
   2.135          {
   2.136              addr = ((addr & ~1) << 1) | plane;
   2.137 -            vram_b(s, addr) = val;
   2.138 +            vram_b = vram_getb(s, addr);
   2.139 +            *vram_b = val;
   2.140 +            vram_put(s, vram_b);
   2.141          }
   2.142      }
   2.143      else
   2.144 @@ -491,9 +508,9 @@ static void stdvga_mem_writeb(uint64_t a
   2.145          /* mask data according to sr[2] */
   2.146          mask = s->sr[2];
   2.147          write_mask = mask16[mask];
   2.148 -        vram_l(s, addr) =
   2.149 -            (vram_l(s, addr) & ~write_mask) |
   2.150 -            (val & write_mask);
   2.151 +        vram_l = vram_getl(s, addr);
   2.152 +        *vram_l = (*vram_l & ~write_mask) | (val & write_mask);
   2.153 +        vram_put(s, vram_l);
   2.154      }
   2.155  }
   2.156  
   2.157 @@ -661,30 +678,33 @@ int stdvga_intercept_mmio(ioreq_t *p)
   2.158  
   2.159  void stdvga_init(struct domain *d)
   2.160  {
   2.161 +    struct hvm_hw_stdvga *s = &d->arch.hvm_domain.stdvga;
   2.162 +    struct page_info *pg;
   2.163 +    void *p;
   2.164      int i;
   2.165 -    struct hvm_hw_stdvga *s = &d->arch.hvm_domain.stdvga;
   2.166 +
   2.167      memset(s, 0, sizeof(*s));
   2.168      spin_lock_init(&s->lock);
   2.169      
   2.170 -    for ( i = 0; i != ARRAY_SIZE(s->vram_ptr); i++ )
   2.171 +    for ( i = 0; i != ARRAY_SIZE(s->vram_page); i++ )
   2.172      {
   2.173 -        struct page_info *vram_page;
   2.174 -        vram_page = alloc_domheap_page(NULL);
   2.175 -        if ( vram_page == NULL )
   2.176 +        if ( (pg = alloc_domheap_page(NULL)) == NULL )
   2.177              break;
   2.178 -        s->vram_ptr[i] = page_to_virt(vram_page);
   2.179 -        memset(s->vram_ptr[i], 0, PAGE_SIZE);
   2.180 +        s->vram_page[i] = pg;
   2.181 +        p = map_domain_page(page_to_mfn(pg));
   2.182 +        clear_page(p);
   2.183 +        unmap_domain_page(p);
   2.184      }
   2.185  
   2.186 -    if ( i == ARRAY_SIZE(s->vram_ptr) )
   2.187 +    if ( i == ARRAY_SIZE(s->vram_page) )
   2.188      {
   2.189          /* Sequencer registers. */
   2.190          register_portio_handler(d, 0x3c4, 2, stdvga_intercept_pio);
   2.191          /* Graphics registers. */
   2.192          register_portio_handler(d, 0x3ce, 2, stdvga_intercept_pio);
   2.193          /* MMIO. */
   2.194 -        register_buffered_io_handler(d, 0xa0000, 0x10000,
   2.195 -                                     stdvga_intercept_mmio);
   2.196 +        register_buffered_io_handler(
   2.197 +            d, 0xa0000, 0x10000, stdvga_intercept_mmio);
   2.198      }
   2.199  }
   2.200  
   2.201 @@ -693,13 +713,11 @@ void stdvga_deinit(struct domain *d)
   2.202      struct hvm_hw_stdvga *s = &d->arch.hvm_domain.stdvga;
   2.203      int i;
   2.204  
   2.205 -    for ( i = 0; i != ARRAY_SIZE(s->vram_ptr); i++ )
   2.206 +    for ( i = 0; i != ARRAY_SIZE(s->vram_page); i++ )
   2.207      {
   2.208 -        struct page_info *vram_page;
   2.209 -        if ( s->vram_ptr[i] == NULL )
   2.210 +        if ( s->vram_page[i] == NULL )
   2.211              continue;
   2.212 -        vram_page = virt_to_page(s->vram_ptr[i]);
   2.213 -        free_domheap_page(vram_page);
   2.214 -        s->vram_ptr[i] = NULL;
   2.215 +        free_domheap_page(s->vram_page[i]);
   2.216 +        s->vram_page[i] = NULL;
   2.217      }
   2.218  }
     3.1 --- a/xen/include/asm-x86/hvm/io.h	Thu Nov 15 22:14:13 2007 +0000
     3.2 +++ b/xen/include/asm-x86/hvm/io.h	Fri Nov 16 14:40:22 2007 +0000
     3.3 @@ -159,8 +159,6 @@ extern void hvm_io_assist(void);
     3.4  extern void hvm_dpci_eoi(struct domain *d, unsigned int guest_irq,
     3.5                           union vioapic_redir_entry *ent);
     3.6  
     3.7 -#ifdef __x86_64__
     3.8 -
     3.9  struct hvm_hw_stdvga {
    3.10      uint8_t sr_index;
    3.11      uint8_t sr[0x18];
    3.12 @@ -169,20 +167,12 @@ struct hvm_hw_stdvga {
    3.13      uint32_t latch;
    3.14      int stdvga;
    3.15      int cache;
    3.16 -    uint8_t *vram_ptr[64];  /* shadow of 0xa0000-0xaffff */
    3.17 +    struct page_info *vram_page[64];  /* shadow of 0xa0000-0xaffff */
    3.18      spinlock_t lock;
    3.19  };
    3.20  
    3.21  void stdvga_init(struct domain *d);
    3.22  void stdvga_deinit(struct domain *d);
    3.23  
    3.24 -#else /* __i386__ */
    3.25 -
    3.26 -struct hvm_hw_stdvga {};
    3.27 -#define stdvga_init(d)   ((void)0)
    3.28 -#define stdvga_deinit(d) ((void)0)
    3.29 -
    3.30 -#endif
    3.31 -
    3.32  #endif /* __ASM_X86_HVM_IO_H__ */
    3.33