direct-io.hg

changeset 5615:4669354bba9a

bitkeeper revision 1.1780 (42c3a8c4tqEOpGy663gWO35k5QwZTw)

[PATCH] Infrastructure for interrupt handling.

Infrastructure for interrupt handling.

- support interruptibility
- handle interrupt window exiting control appropriately
- Add ioapic device models imported from Bochs under LGPL
- generalize the interrupt architecture to support both PIC/APIC

This patch is necessary to fix several bugs on 32 bit VMX and prepares the
ground for adding a local APIC device model in the hypervisor.

Signed-off-by: Yunhong Jiang <yunhong.jiang@intel.com>
Signed-off-by: Eddie Dong <eddie.dong@intel.com>
Signed-off-by: Arun Sharma <arun.sharma@intel.com>
author arun.sharma@intel.com[kaf24]
date Thu Jun 30 08:09:40 2005 +0000 (2005-06-30)
parents bc8bb3a26ccc
children 800185829318
files .rootkeys tools/ioemu/exec-all.h tools/ioemu/hw/i8259.c tools/ioemu/hw/ioapic.c tools/ioemu/hw/ioapic.h tools/ioemu/hw/pc.c tools/ioemu/hw/pci.c tools/ioemu/target-i386-dm/Makefile tools/ioemu/target-i386-dm/helper2.c xen/arch/x86/vmx_intercept.c xen/arch/x86/vmx_io.c xen/arch/x86/vmx_vmcs.c xen/include/asm-x86/vmx.h xen/include/asm-x86/vmx_virpit.h xen/include/public/io/ioreq.h xen/include/public/io/vmx_vlapic.h
line diff
     1.1 --- a/.rootkeys	Thu Jun 30 08:09:23 2005 +0000
     1.2 +++ b/.rootkeys	Thu Jun 30 08:09:40 2005 +0000
     1.3 @@ -681,6 +681,8 @@ 428d0d84-hHRu7PVXjfc7oLfrDxY6g tools/ioe
     1.4  428d0d84zbtT2C8Xci_SqMP5bZ-wcQ tools/ioemu/hw/i8254.c
     1.5  428d0d84KlR61OwSzjF0-L4iz58dfQ tools/ioemu/hw/i8259.c
     1.6  428d0d84auhZx6c5Kv3WrfM2UZvqHA tools/ioemu/hw/ide.c
     1.7 +42c3a8bcqaiyuOWldKc1vXUP12-1Bg tools/ioemu/hw/ioapic.c
     1.8 +42c3a8bcMP67Od-xEnQaYAHahibD_w tools/ioemu/hw/ioapic.h
     1.9  428d0d84WSlhNzdrcb-f-Lg-W9dniQ tools/ioemu/hw/iommu.c
    1.10  428d0d84ri8ZtvhB6RJr1YNejjNWIQ tools/ioemu/hw/lance.c
    1.11  428d0d84cxFFgDv5fBFrlxGoCiy6Nw tools/ioemu/hw/m48t08.c
    1.12 @@ -1570,6 +1572,7 @@ 41c0c412FLc0gunlJl91qMYscFtXVA xen/inclu
    1.13  40f5623cTZ80EwjWUBlh44A9F9i_Lg xen/include/public/io/netif.h
    1.14  41d40e9b8zCk5VDqhVbuQyhc7G3lqA xen/include/public/io/ring.h
    1.15  41ee5e8c6mLxIx82KPsbpt_uts_vSA xen/include/public/io/usbif.h
    1.16 +42c3a8bcUFXJKVc8tWCFilICv2cNaA xen/include/public/io/vmx_vlapic.h
    1.17  4051db79512nOCGweabrFWO2M2h5ng xen/include/public/physdev.h
    1.18  42b742f7Lzy8SKKG25L_-fgk5FHA2Q xen/include/public/policy_ops.h
    1.19  40589968wmhPmV5-ENbBYmMjnedgKw xen/include/public/sched_ctl.h
     2.1 --- a/tools/ioemu/exec-all.h	Thu Jun 30 08:09:23 2005 +0000
     2.2 +++ b/tools/ioemu/exec-all.h	Thu Jun 30 08:09:40 2005 +0000
     2.3 @@ -573,7 +573,7 @@ static inline target_ulong get_phys_addr
     2.4  }
     2.5  #endif
     2.6  
     2.7 -//#define DEBUG_UNUSED_IOPORT
     2.8 -//#define DEBUG_IOPORT
     2.9 +#define DEBUG_UNUSED_IOPORT
    2.10 +#define DEBUG_IOPORT
    2.11  #define TARGET_VMX
    2.12  
     3.1 --- a/tools/ioemu/hw/i8259.c	Thu Jun 30 08:09:23 2005 +0000
     3.2 +++ b/tools/ioemu/hw/i8259.c	Thu Jun 30 08:09:40 2005 +0000
     3.3 @@ -22,6 +22,8 @@
     3.4   * THE SOFTWARE.
     3.5   */
     3.6  #include "vl.h"
     3.7 +#include "xc.h"
     3.8 +#include <io/ioreq.h>
     3.9  
    3.10  /* debug PIC */
    3.11  //#define DEBUG_PIC
    3.12 @@ -29,6 +31,8 @@
    3.13  //#define DEBUG_IRQ_LATENCY
    3.14  #define DEBUG_IRQ_COUNT
    3.15  
    3.16 +extern void pit_reset_vmx_vectors();
    3.17 +
    3.18  typedef struct PicState {
    3.19      uint8_t last_irr; /* edge detection */
    3.20      uint8_t irr; /* interrupt request register */
    3.21 @@ -121,6 +125,26 @@ static int pic_get_irq(PicState *s)
    3.22      }
    3.23  }
    3.24  
    3.25 +/* pic[1] is connected to pin2 of pic[0] */
    3.26 +#define CASCADE_IRQ 2
    3.27 +
    3.28 +static void shared_page_update()
    3.29 +{
    3.30 +    extern shared_iopage_t *shared_page;
    3.31 +    uint8_t * pmask = (uint8_t *)&(shared_page->sp_global.pic_mask[0]);
    3.32 +    int           index;
    3.33 +
    3.34 +    index = pics[0].irq_base/8;
    3.35 +    pmask[index] = pics[0].imr;
    3.36 +    index = pics[1].irq_base/8;
    3.37 +
    3.38 +    if ( pics[0].imr &  (1 << CASCADE_IRQ) ) {
    3.39 +        pmask[index] = 0xff;
    3.40 +    } else {
    3.41 +        pmask[index] = pics[1].imr;
    3.42 +    }
    3.43 +}
    3.44 +
    3.45  /* raise irq to CPU if necessary. must be called every time the active
    3.46     irq may change */
    3.47  static void pic_update_irq(void)
    3.48 @@ -150,14 +174,18 @@ static void pic_update_irq(void)
    3.49  #endif
    3.50          cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HARD);
    3.51      }
    3.52 +    shared_page_update();
    3.53  }
    3.54  
    3.55  #ifdef DEBUG_IRQ_LATENCY
    3.56  int64_t irq_time[16];
    3.57  #endif
    3.58  
    3.59 +extern void ioapic_legacy_irq(int irq, int level);
    3.60 +
    3.61  void pic_set_irq(int irq, int level)
    3.62  {
    3.63 +    ioapic_legacy_irq(irq, level);
    3.64  #if defined(DEBUG_PIC) || defined(DEBUG_IRQ_COUNT)
    3.65      if (level != irq_level[irq]) {
    3.66  #if defined(DEBUG_PIC)
    3.67 @@ -255,6 +283,7 @@ static void pic_reset(void *opaque)
    3.68      tmp = s->elcr_mask;
    3.69      memset(s, 0, sizeof(PicState));
    3.70      s->elcr_mask = tmp;
    3.71 +    shared_page_update();
    3.72  }
    3.73  
    3.74  static void pic_ioport_write(void *opaque, uint32_t addr, uint32_t val)
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/tools/ioemu/hw/ioapic.c	Thu Jun 30 08:09:40 2005 +0000
     4.3 @@ -0,0 +1,704 @@
     4.4 +/////////////////////////////////////////////////////////////////////////
     4.5 +//
     4.6 +//  Copyright (C) 2001  MandrakeSoft S.A.
     4.7 +//
     4.8 +//    MandrakeSoft S.A.
     4.9 +//    43, rue d'Aboukir
    4.10 +//    75002 Paris - France
    4.11 +//    http://www.linux-mandrake.com/
    4.12 +//    http://www.mandrakesoft.com/
    4.13 +//
    4.14 +//  This library is free software; you can redistribute it and/or
    4.15 +//  modify it under the terms of the GNU Lesser General Public
    4.16 +//  License as published by the Free Software Foundation; either
    4.17 +//  version 2 of the License, or (at your option) any later version.
    4.18 +//
    4.19 +//  This library is distributed in the hope that it will be useful,
    4.20 +//  but WITHOUT ANY WARRANTY; without even the implied warranty of
    4.21 +//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    4.22 +//  Lesser General Public License for more details.
    4.23 +//
    4.24 +//  You should have received a copy of the GNU Lesser General Public
    4.25 +//  License along with this library; if not, write to the Free Software
    4.26 +//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
    4.27 +//
    4.28 +
    4.29 +#include "vl.h"
    4.30 +#include "ioapic.h"
    4.31 +
    4.32 +#ifdef __OS
    4.33 +#undef __OS
    4.34 +#endif
    4.35 +#ifdef __i386__
    4.36 +#define __OS	"l"
    4.37 +#else
    4.38 +#define __OS "q"
    4.39 +#endif
    4.40 +#define ADDR (*(volatile long *) addr)
    4.41 +
    4.42 +#ifdef IOAPIC_DEBUG
    4.43 +#define IOAPIC_LOG(a...) fprintf(logfile, ##a)
    4.44 +#else
    4.45 +#define IOAPIC_LOG(a...)
    4.46 +#endif
    4.47 +
    4.48 +static IOAPICState *ioapic;
    4.49 +
    4.50 +#define IOAPIC_ERR(a...) fprintf(logfile, ##a)
    4.51 +static __inline__ int test_and_set_bit(long nr, volatile void * addr)
    4.52 +{
    4.53 +	long oldbit;
    4.54 +
    4.55 +	__asm__ __volatile__( 
    4.56 +		"bts"__OS" %2,%1\n\tsbb"__OS" %0,%0"
    4.57 +		:"=r" (oldbit),"=m" (ADDR)
    4.58 +		:"Ir" (nr) : "memory");
    4.59 +	return oldbit;
    4.60 +}
    4.61 +
    4.62 +static __inline__ int test_and_clear_bit(long nr, volatile void * addr)
    4.63 +{
    4.64 +	long oldbit;
    4.65 +
    4.66 +	__asm__ __volatile__( LOCK_PREFIX
    4.67 +		"btr"__OS" %2,%1\n\tsbb"__OS" %0,%0"
    4.68 +		:"=r" (oldbit),"=m" (ADDR)
    4.69 +		:"dIr" (nr) : "memory");
    4.70 +	return oldbit;
    4.71 +}
    4.72 +
    4.73 +static __inline__ void clear_bit(long nr, volatile void * addr)
    4.74 +{
    4.75 +	__asm__ __volatile__( 
    4.76 +		"btr"__OS" %1,%0"
    4.77 +		:"=m" (ADDR)
    4.78 +		:"Ir" (nr));
    4.79 +}
    4.80 +
    4.81 +static inline
    4.82 +void get_shareinfo_apic_msg(vlapic_info *share_info){
    4.83 +    while(test_and_set_bit(VL_STATE_MSG_LOCK, &share_info->vl_state)){};
    4.84 +}
    4.85 +
    4.86 +static inline
    4.87 +void put_shareinfo_apic_msg(vlapic_info *share_info){
    4.88 +    clear_bit(VL_STATE_MSG_LOCK, &share_info->vl_state);
    4.89 +}
    4.90 +static inline
    4.91 +void get_shareinfo_eoi(vlapic_info *share_info){
    4.92 +    while(test_and_set_bit(VL_STATE_EOI_LOCK, &share_info->vl_state)){};
    4.93 +}
    4.94 +
    4.95 +static inline
    4.96 +void put_shareinfo_eoi(vlapic_info *share_info){
    4.97 +    clear_bit(VL_STATE_EOI_LOCK, &share_info->vl_state);
    4.98 +}
    4.99 +
   4.100 +
   4.101 +static inline
   4.102 +void get_shareinfo_ext(vlapic_info *share_info){
   4.103 +    while(test_and_set_bit(VL_STATE_EXT_LOCK, &share_info->vl_state));
   4.104 +}
   4.105 +
   4.106 +static inline
   4.107 +void put_shareinfo_ext(vlapic_info *share_info){
   4.108 +    clear_bit(VL_STATE_EXT_LOCK, &share_info->vl_state);
   4.109 +}
   4.110 +
   4.111 +
   4.112 +static __inline__ int test_bit(int nr, uint32_t value){
   4.113 +    return value & (1 << nr);
   4.114 +}
   4.115 +
   4.116 +static void ioapic_enable(IOAPICState *s, uint8_t enable)
   4.117 +{
   4.118 +    if (!enable ^ IOAPICEnabled(s)) return;
   4.119 +    if(enable)
   4.120 +        s->flags |= IOAPIC_ENABLE_FLAG;
   4.121 +    else
   4.122 +        s->flags &= ~IOAPIC_ENABLE_FLAG;
   4.123 +}
   4.124 +
   4.125 +#ifdef IOAPIC_DEBUG
   4.126 +static void
   4.127 +ioapic_dump_redir(IOAPICState *s, uint8_t entry)
   4.128 +{
   4.129 +    if (!s)
   4.130 +        return;
   4.131 +
   4.132 +    RedirStatus redir = s->redirtbl[entry];
   4.133 +
   4.134 +    fprintf(logfile, "entry %x: "
   4.135 +      "vector %x deliver_mod %x destmode %x delivestatus %x "
   4.136 +      "polarity %x remote_irr %x trigmod %x mask %x dest_id %x\n",
   4.137 +      entry,
   4.138 +      redir.RedirForm.vector, redir.RedirForm.deliver_mode,
   4.139 +      redir.RedirForm.destmode, redir.RedirForm.delivestatus,
   4.140 +      redir.RedirForm.polarity, redir.RedirForm.remoteirr,
   4.141 +      redir.RedirForm.trigmod, redir.RedirForm.mask,
   4.142 +      redir.RedirForm.dest_id);
   4.143 +}
   4.144 +
   4.145 +static void
   4.146 +ioapic_dump_shareinfo(IOAPICState *s , int number)
   4.147 +{
   4.148 +    if (!s || !s->lapic_info[number])
   4.149 +        return;
   4.150 +    vlapic_info *m = s->lapic_info[number];
   4.151 +    IOAPIC_LOG("lapic_info %x : "
   4.152 +      "vl_lapic_id %x vl_logical_dest %x vl_dest_format %x vl_arb_id %x\n",
   4.153 +      number, m->vl_lapic_id, m->vl_logical_dest, m->vl_dest_format, m->vl_arb_id );
   4.154 +}
   4.155 +#endif
   4.156 +
   4.157 +static void
   4.158 +ioapic_save(QEMUFile* f,void* opaque)
   4.159 +{
   4.160 +    IOAPIC_ERR("no implementation for ioapic_save\n");
   4.161 +}
   4.162 +
   4.163 +static
   4.164 +int ioapic_load(QEMUFile* f,void* opaque,int version_id)
   4.165 +{
   4.166 +    IOAPIC_ERR("no implementation for ioapic_load\n");
   4.167 +    return 0;
   4.168 +}
   4.169 +
   4.170 +uint32_t
   4.171 +ioapic_mem_readb(void *opaque, target_phys_addr_t addr)
   4.172 +{
   4.173 +    IOAPIC_ERR("ioapic_mem_readb\n");
   4.174 +    return 0;
   4.175 +}
   4.176 +
   4.177 +uint32_t
   4.178 +ioapic_mem_readw(void *opaque, target_phys_addr_t addr)
   4.179 +{
   4.180 +    IOAPIC_ERR("ioapic_mem_readw\n");
   4.181 +    return 0;
   4.182 +}
   4.183 +
   4.184 +static
   4.185 +void ioapic_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
   4.186 +{
   4.187 +    IOAPIC_ERR("ioapic_mem_writeb\n");
   4.188 +}
   4.189 +
   4.190 +static
   4.191 +void ioapic_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
   4.192 +{
   4.193 +    IOAPIC_ERR("ioapic_mem_writew\n");
   4.194 +}
   4.195 +
   4.196 +static
   4.197 +uint32_t ioapic_mem_readl(void *opaque, target_phys_addr_t addr)
   4.198 +{
   4.199 +    unsigned short ioregsel;
   4.200 +    IOAPICState *s = opaque;
   4.201 +    uint32_t    result = 0;
   4.202 +    uint32_t    redir_index = 0;
   4.203 +    uint64_t    redir_content = 0;
   4.204 +
   4.205 +    IOAPIC_LOG("apic_mem_readl addr %x\n", addr);
   4.206 +    if (!s){
   4.207 +        IOAPIC_ERR("null pointer for apic_mem_readl\n");
   4.208 +        return result;
   4.209 +    }
   4.210 +
   4.211 +    addr &= 0xff;
   4.212 +    if(addr == 0x00){
   4.213 +        result = s->ioregsel;
   4.214 +        return result;
   4.215 +    }else if (addr != 0x10){
   4.216 +        IOAPIC_ERR("apic_mem_readl address error\n");
   4.217 +        return result;
   4.218 +    }
   4.219 +
   4.220 +    ioregsel = s->ioregsel;
   4.221 +
   4.222 +    switch (ioregsel){
   4.223 +        case IOAPIC_REG_APIC_ID:
   4.224 +            result = ((s->id & 0xf) << 24);
   4.225 +            break;
   4.226 +        case IOAPIC_REG_VERSION:
   4.227 +            result = ((((IOAPIC_NUM_PINS-1) & 0xff) << 16)  
   4.228 +                     | (IOAPIC_VERSION_ID & 0x0f));
   4.229 +            break;
   4.230 +        case IOAPIC_REG_ARB_ID:
   4.231 +            //FIXME
   4.232 +            result = ((s->id & 0xf) << 24);
   4.233 +            break;
   4.234 +        default:
   4.235 +            redir_index = (ioregsel - 0x10) >> 1;
   4.236 +            if (redir_index >= 0 && redir_index < IOAPIC_NUM_PINS){
   4.237 +               redir_content = s->redirtbl[redir_index].value;
   4.238 +               result = (ioregsel & 0x1)?
   4.239 +                        (redir_content >> 32) & 0xffffffff :
   4.240 +                        redir_content & 0xffffffff;
   4.241 +            }else{
   4.242 +                IOAPIC_ERR(
   4.243 +                  "upic_mem_readl:undefined ioregsel %x\n",
   4.244 +                  ioregsel);
   4.245 +            }
   4.246 +    }
   4.247 +    return result;
   4.248 +}
   4.249 +
   4.250 +static
   4.251 +void ioapic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
   4.252 +{
   4.253 +    IOAPICState *s = opaque;
   4.254 +    uint32_t redir_index = 0;
   4.255 +    uint64_t redir_content;
   4.256 +
   4.257 +    IOAPIC_LOG("apic_mem_writel addr %x val %x\n", addr, val);
   4.258 +
   4.259 +    if (!s){
   4.260 +        IOAPIC_ERR("apic_mem_writel: null opaque\n");
   4.261 +        return;
   4.262 +    }
   4.263 +
   4.264 +    addr &= 0xff;
   4.265 +    if (addr == 0x00){
   4.266 +        s->ioregsel = val;
   4.267 +        return;
   4.268 +    }else if (addr != 0x10){
   4.269 +        IOAPIC_ERR("apic_mem_writel: unsupported address\n");
   4.270 +    }
   4.271 +
   4.272 +    switch (s->ioregsel){
   4.273 +        case IOAPIC_REG_APIC_ID:
   4.274 +            s->id = (val >> 24) & 0xf;
   4.275 +            break;
   4.276 +        case IOAPIC_REG_VERSION:
   4.277 +            IOAPIC_ERR("apic_mem_writel: version register read only\n");
   4.278 +            break;
   4.279 +        case IOAPIC_REG_ARB_ID:
   4.280 +            s->arb_id = val;
   4.281 +            break;
   4.282 +        default:
   4.283 +            redir_index = (s->ioregsel - 0x10) >> 1;
   4.284 +//            IOAPIC_LOG("apic_mem_write: change redir :index %x before %lx, val %x\n", redir_index, s->redirtbl[redir_index].value, val);
   4.285 +            if (redir_index >= 0 && redir_index < IOAPIC_NUM_PINS){
   4.286 +                redir_content = s->redirtbl[redir_index].value;
   4.287 +                if (s->ioregsel & 0x1)
   4.288 +                   redir_content = (((uint64_t)val & 0xffffffff) << 32) | (redir_content & 0xffffffff);
   4.289 +                else
   4.290 +                    redir_content = ((redir_content >> 32) << 32) | (val & 0xffffffff);
   4.291 +                s->redirtbl[redir_index].value = redir_content;
   4.292 +            }else {
   4.293 +                IOAPIC_ERR("apic_mem_writel: error register\n");
   4.294 +            }
   4.295 +            //IOAPIC_LOG("after value is %lx\n",  s->redirtbl[redir_index].value);
   4.296 +    }
   4.297 +}
   4.298 +
   4.299 +static CPUReadMemoryFunc *ioapic_mem_read[3] = {
   4.300 +    ioapic_mem_readb,
   4.301 +    ioapic_mem_readw,
   4.302 +    ioapic_mem_readl,
   4.303 +};
   4.304 +
   4.305 +static CPUWriteMemoryFunc *ioapic_mem_write[3] = {
   4.306 +    ioapic_mem_writeb,
   4.307 +    ioapic_mem_writew,
   4.308 +    ioapic_mem_writel,
   4.309 +};
   4.310 +
   4.311 +void
   4.312 +IOAPICReset(IOAPICState *s)
   4.313 +{
   4.314 +    int i;
   4.315 +    if (!s)
   4.316 +        return ;
   4.317 +
   4.318 +    memset(s, 0, sizeof(IOAPICState));
   4.319 +
   4.320 +    for (i = 0; i < IOAPIC_NUM_PINS; i++)
   4.321 +        s->redirtbl[i].RedirForm.mask = 0x1;
   4.322 +//    IOAPIC_LOG("after Reset %lx\n",  s->redirtbl[0].value);
   4.323 +}
   4.324 +
   4.325 +void
   4.326 +ioapic_update_config(IOAPICState *s, unsigned long address, uint8_t enable)
   4.327 +{
   4.328 +    int ioapic_mem;
   4.329 +    if (!s)
   4.330 +       return;
   4.331 +
   4.332 +    ioapic_enable(s, enable);
   4.333 +
   4.334 +    if (address != s->base_address){
   4.335 +        ioapic_mem = cpu_register_io_memory(0, ioapic_mem_read, ioapic_mem_write, s);
   4.336 +        cpu_register_physical_memory(address, IOAPIC_MEM_LENGTH, ioapic_mem);
   4.337 +        s->base_address = ioapic_mem;
   4.338 +    }
   4.339 +}
   4.340 +
   4.341 +#define direct_intr(mode)   \
   4.342 +  (mode == VLAPIC_DELIV_MODE_SMI || \
   4.343 +   mode == VLAPIC_DELIV_MODE_NMI || \
   4.344 +   mode == VLAPIC_DELIV_MODE_INIT ||\
   4.345 +   mode == VLAPIC_DELIV_MODE_STARTUP)
   4.346 +
   4.347 +int
   4.348 +ioapic_inj_irq(IOAPICState *s, uint8_t dest, uint8_t vector, uint8_t trig_mode, uint8_t delivery_mode)
   4.349 +{
   4.350 +    int msg_count;
   4.351 +    if (!s || !s->lapic_info[dest]){
   4.352 +        IOAPIC_ERR("ioapic_inj_irq NULL parameter\n");
   4.353 +        return 0;
   4.354 +    }
   4.355 +    IOAPIC_LOG("ioapic_inj_irq %d , trig %d delive mode %d\n",
   4.356 +      vector, trig_mode, delivery_mode);
   4.357 +    switch(delivery_mode){
   4.358 +        case VLAPIC_DELIV_MODE_FIXED:
   4.359 +        case VLAPIC_DELIV_MODE_LPRI:
   4.360 +            get_shareinfo_apic_msg(s->lapic_info[dest]);
   4.361 +            msg_count = s->lapic_info[dest]->apic_msg_count;
   4.362 +            s->lapic_info[dest]->vl_apic_msg[msg_count].deliv_mode = delivery_mode;
   4.363 +            s->lapic_info[dest]->vl_apic_msg[msg_count].level = trig_mode;
   4.364 +            s->lapic_info[dest]->vl_apic_msg[msg_count].vector = vector;
   4.365 +            s->lapic_info[dest]->vl_apic_msg[msg_count].vector = vector;
   4.366 +            s->lapic_info[dest]->apic_msg_count ++;
   4.367 +            put_shareinfo_apic_msg(s->lapic_info[dest]);
   4.368 +            break;
   4.369 +        case VLAPIC_DELIV_MODE_EXT:
   4.370 +/*            get_shareinfo_ext(s->lapic_info[dest]);
   4.371 +            test_and_set_bit(vector, &s->lapic_info[dest]->vl_ext_intr[0]);
   4.372 +            put_shareinfo_ext(s->lapic_info[dest]);*/
   4.373 +            IOAPIC_ERR("<ioapic_inj_irq> Ext interrupt\n");
   4.374 +            return 0;
   4.375 +        default:
   4.376 +            IOAPIC_ERR("<ioapic_inj_irq> error delivery mode\n");
   4.377 +            break;
   4.378 +    }
   4.379 +    return 1;
   4.380 +}
   4.381 +
   4.382 +int
   4.383 +ioapic_match_logical_addr(IOAPICState *s, int number, uint8_t address)
   4.384 +{
   4.385 +    if(!s || !s->lapic_info[number]){
   4.386 +        IOAPIC_ERR("ioapic_match_logical_addr NULL parameter: "
   4.387 +          "number: %i s %p address %x\n",
   4.388 +          number, s, address);
   4.389 +        return 0;
   4.390 +    }
   4.391 +    IOAPIC_LOG("ioapic_match_logical_addr number %i address %x\n",
   4.392 +      number, address);
   4.393 +
   4.394 +    if (((s->lapic_info[number]->vl_dest_format >> 28 ) & 0xf) != 0xf) {
   4.395 +        IOAPIC_ERR("ioapic_match_logical_addr: cluster model not implemented still%x"
   4.396 +          ,s->lapic_info[number]->vl_dest_format);
   4.397 +#ifdef IOAPIC_DEBUG
   4.398 +        ioapic_dump_shareinfo(s, number);
   4.399 +#endif
   4.400 +        return 0;
   4.401 +    }
   4.402 +    return ((address & ((s->lapic_info[number]->vl_logical_dest >> 24) & 0xff)) != 0);
   4.403 +}
   4.404 +
   4.405 +int
   4.406 +ioapic_get_apr_lowpri(IOAPICState *s, int number)
   4.407 +{
   4.408 +    if(!s || !s->lapic_info[number]){
   4.409 +        IOAPIC_ERR("ioapic_get_apr_lowpri NULL parameter\n");
   4.410 +        return 0;
   4.411 +    }
   4.412 +    return s->lapic_info[number]->vl_arb_id;
   4.413 +}
   4.414 +
   4.415 +uint32_t
   4.416 +ioapic_get_delivery_bitmask(IOAPICState *s,
   4.417 +uint8_t dest, uint8_t dest_mode, uint8_t vector, uint8_t delivery_mode)
   4.418 +{
   4.419 +    uint32_t mask = 0;
   4.420 +    int low_priority = 256, selected = -1, i;
   4.421 +    fprintf(logfile, "<ioapic_get_delivery_bitmask>: dest %d dest_mode %d"
   4.422 +      "vector %d del_mode %d, lapic_count %d\n",
   4.423 +      dest, dest_mode, vector, delivery_mode, s->lapic_count);
   4.424 +    if (!s) return mask;
   4.425 +    if (dest_mode == 0) { //Physical mode
   4.426 +        if ((dest < s->lapic_count) && s->lapic_info[dest])
   4.427 +            mask = 1 << dest;
   4.428 +    }
   4.429 +    else {
   4.430 +        /* logical destination. call match_logical_addr for each APIC. */
   4.431 +        if (dest == 0) return 0;
   4.432 +        for (i=0; i< s->lapic_count; i++) {
   4.433 +            //FIXME focus one, since no such issue on IPF, shoudl we add it?
   4.434 +            if ( s->lapic_info[i] && ioapic_match_logical_addr(s, i, dest)){
   4.435 +                if (delivery_mode != APIC_DM_LOWPRI)
   4.436 +                    mask |= (1<<i);
   4.437 +                else {
   4.438 +                    if (low_priority > ioapic_get_apr_lowpri(s, i)){
   4.439 +                        low_priority = ioapic_get_apr_lowpri(s, i);
   4.440 +                        selected = i;
   4.441 +                    }
   4.442 +                    fprintf(logfile, "%d low_priority %d apr %d select %d\n",
   4.443 +                      i, low_priority, ioapic_get_apr_lowpri(s, i), selected);
   4.444 +                }
   4.445 +            }
   4.446 +        }
   4.447 +        if (delivery_mode == APIC_DM_LOWPRI && (selected != -1)) 
   4.448 +            mask |= (1<< selected);
   4.449 +    }
   4.450 +  return mask;
   4.451 +}
   4.452 +
   4.453 +void
   4.454 +ioapic_deliver(IOAPICState *s, int irqno){
   4.455 +    uint8_t dest = s->redirtbl[irqno].RedirForm.dest_id;
   4.456 +    uint8_t dest_mode = s->redirtbl[irqno].RedirForm.destmode;
   4.457 +    uint8_t delivery_mode = s->redirtbl[irqno].RedirForm.deliver_mode;
   4.458 +    uint8_t vector = s->redirtbl[irqno].RedirForm.vector;
   4.459 +    uint8_t trig_mode = s->redirtbl[irqno].RedirForm.trigmod;
   4.460 +    uint8_t bit;
   4.461 +    uint32_t deliver_bitmask; 
   4.462 +
   4.463 +    IOAPIC_LOG("IOAPIC deliver: "
   4.464 +      "dest %x dest_mode %x delivery_mode %x vector %x trig_mode %x\n",
   4.465 +      dest, dest_mode, delivery_mode, vector, trig_mode);
   4.466 +
   4.467 +    deliver_bitmask =
   4.468 +      ioapic_get_delivery_bitmask(s, dest, dest_mode, vector, delivery_mode);
   4.469 +
   4.470 +      IOAPIC_LOG("ioapic_get_delivery_bitmask return %x\n", deliver_bitmask);
   4.471 +    if (!deliver_bitmask){
   4.472 +        IOAPIC_ERR("Ioapic deliver, no target on destination\n");
   4.473 +        return ;
   4.474 +    }
   4.475 +
   4.476 +    switch (delivery_mode){
   4.477 +        case VLAPIC_DELIV_MODE_FIXED:
   4.478 +        case VLAPIC_DELIV_MODE_LPRI:
   4.479 +        case VLAPIC_DELIV_MODE_EXT:
   4.480 +            break;
   4.481 +        case VLAPIC_DELIV_MODE_SMI:
   4.482 +        case VLAPIC_DELIV_MODE_NMI:
   4.483 +        case VLAPIC_DELIV_MODE_INIT:
   4.484 +        case VLAPIC_DELIV_MODE_STARTUP:
   4.485 +        default:
   4.486 +            IOAPIC_ERR("Not support delivey mode %d\n", delivery_mode);
   4.487 +            return ;
   4.488 +    }
   4.489 +
   4.490 +    for (bit = 0; bit < s->lapic_count; bit++){
   4.491 +        if (deliver_bitmask & (1 << bit)){
   4.492 +            if (s->lapic_info[bit]){
   4.493 +                ioapic_inj_irq(s, bit, vector, trig_mode, delivery_mode);
   4.494 +            }
   4.495 +        }
   4.496 +    }
   4.497 +}
   4.498 +
   4.499 +static inline int __fls(u32 word)
   4.500 +{
   4.501 +    int bit;
   4.502 +    __asm__("bsrl %1,%0"
   4.503 +      :"=r" (bit)
   4.504 +      :"rm" (word));
   4.505 +    return word ? bit : -1;
   4.506 +}
   4.507 +
   4.508 +#if 0
   4.509 +static __inline__ int find_highest_bit(unsigned long *data, int length){
   4.510 +    while(length && !data[--length]);
   4.511 +    return __fls(data[length]) +  32 * length;
   4.512 +}
   4.513 +#endif
   4.514 +int
   4.515 +ioapic_get_highest_irq(IOAPICState *s){
   4.516 +    uint32_t irqs;
   4.517 +    if (!s)
   4.518 +        return -1;
   4.519 +    irqs = s->irr & ~s->isr;
   4.520 +    return __fls(irqs);
   4.521 +}
   4.522 +
   4.523 +
   4.524 +void
   4.525 +service_ioapic(IOAPICState *s){
   4.526 +    int irqno;
   4.527 +
   4.528 +    while((irqno = ioapic_get_highest_irq(s)) != -1){
   4.529 +        IOAPIC_LOG("service_ioapic: highest irqno %x\n", irqno);
   4.530 +
   4.531 +        if (!s->redirtbl[irqno].RedirForm.mask)
   4.532 +            ioapic_deliver(s, irqno);
   4.533 +
   4.534 +        if (s->redirtbl[irqno].RedirForm.trigmod == IOAPIC_LEVEL_TRIGGER){
   4.535 +            s->isr |= (1 << irqno);
   4.536 +        }
   4.537 + //       clear_bit(irqno, &s->irr);
   4.538 +        s->irr &= ~(1 << irqno);
   4.539 +    }
   4.540 +}
   4.541 +
   4.542 +void
   4.543 +ioapic_update_irq(IOAPICState *s)
   4.544 +{
   4.545 +    s->INTR = 1;
   4.546 +}
   4.547 +
   4.548 +void
   4.549 +ioapic_set_irq(IOAPICState *s, int irq, int level)
   4.550 +{
   4.551 +    IOAPIC_LOG("ioapic_set_irq %x %x\n", irq, level);
   4.552 +
   4.553 +    /* Timer interrupt implemented on HV side */
   4.554 +    if(irq == 0x0) return;
   4.555 +    if (!s){
   4.556 +        fprintf(logfile, "ioapic_set_irq null parameter\n");
   4.557 +        return;
   4.558 +    }
   4.559 +    if (!IOAPICEnabled(s) || s->redirtbl[irq].RedirForm.mask)
   4.560 +        return;
   4.561 +#ifdef IOAPIC_DEBUG
   4.562 +    ioapic_dump_redir(s, irq);
   4.563 +#endif
   4.564 +    if (irq >= 0 && irq < IOAPIC_NUM_PINS){
   4.565 +        uint32_t bit = 1 << irq;
   4.566 +        if (s->redirtbl[irq].RedirForm.trigmod == IOAPIC_LEVEL_TRIGGER){
   4.567 +            if(level)
   4.568 +                s->irr |= bit;
   4.569 +            else
   4.570 +                s->irr &= ~bit;
   4.571 +        }else{
   4.572 +            if(level)
   4.573 +                /* XXX No irr clear for edge interrupt */
   4.574 +                s->irr |= bit;
   4.575 +        }
   4.576 +    }
   4.577 +
   4.578 +    ioapic_update_irq(s);
   4.579 +}
   4.580 +
   4.581 +void
   4.582 +ioapic_legacy_irq(int irq, int level)
   4.583 +{
   4.584 +    ioapic_set_irq(ioapic, irq, level);
   4.585 +}
   4.586 +
   4.587 +static inline int find_highest_bit(u32 *data, int length){
   4.588 +        while(length && !data[--length]);
   4.589 +            return __fls(data[length]) +  32 * length;
   4.590 +}
   4.591 +
   4.592 +int
   4.593 +get_redir_num(IOAPICState *s, int vector){
   4.594 +    int i = 0;
   4.595 +    if(!s){
   4.596 +        IOAPIC_ERR("Null parameter for get_redir_num\n");
   4.597 +        return -1;
   4.598 +    }
   4.599 +    for(; i < IOAPIC_NUM_PINS-1; i++){
   4.600 +        if (s->redirtbl[i].RedirForm.vector == vector)
   4.601 +            return i;
   4.602 +    }
   4.603 +    return -1;
   4.604 +}
   4.605 +
   4.606 +void
   4.607 +ioapic_update_EOI()
   4.608 +{
   4.609 +    int i = 0;
   4.610 +    uint32_t isr_info ;
   4.611 +    uint32_t vector;
   4.612 +    IOAPICState *s = ioapic;
   4.613 +
   4.614 +    isr_info = s->isr;
   4.615 +
   4.616 +    for (i = 0; i < s->lapic_count; i++){
   4.617 +        if (!s->lapic_info[i] ||
   4.618 +          !test_bit(VL_STATE_EOI, s->lapic_info[i]->vl_state))
   4.619 +            continue;
   4.620 +        get_shareinfo_eoi(s->lapic_info[i]);
   4.621 +        while((vector = find_highest_bit((unsigned int *)&s->lapic_info[i]->vl_eoi[0],VLAPIC_INT_COUNT_32)) != -1){
   4.622 +            int redir_num;
   4.623 +            if ((redir_num = get_redir_num(s, vector)) == -1){
   4.624 +                IOAPIC_ERR("Can't find redir item for %d EOI \n", vector);
   4.625 +                continue;
   4.626 +            }
   4.627 +            if (!test_and_clear_bit(redir_num, &s->isr)){
   4.628 +                IOAPIC_ERR("redir %d not set for %d  EOI\n", redir_num, vector);
   4.629 +                continue;
   4.630 +            }
   4.631 +            clear_bit(vector, &s->lapic_info[i]->vl_eoi[0]); 
   4.632 +        }
   4.633 +        clear_bit(VL_STATE_EOI, &s->lapic_info[i]->vl_state);
   4.634 +        put_shareinfo_eoi(s->lapic_info[i]);
   4.635 +    }
   4.636 +}
   4.637 +
   4.638 +
   4.639 +void
   4.640 +ioapic_init_apic_info(IOAPICState *s)
   4.641 +{
   4.642 +#ifdef IOAPIC_DEBUG
   4.643 +    fprintf(logfile, "ioapic_init_apic_info\n");
   4.644 +    if (!s)
   4.645 +        return;
   4.646 +#endif
   4.647 +
   4.648 +#if 0
   4.649 +    if (!vio || !(vio->vl_number)){
   4.650 +        fprintf(logfile, "null vio or o vl number\n");
   4.651 +        return;
   4.652 +    }
   4.653 +
   4.654 +    for (i = 0; i < MAX_LAPIC_NUM; i++) s->lapic_info[i] = NULL;
   4.655 +
   4.656 +    s->lapic_count = vio->vl_number;
   4.657 +    for (i = 0; i < vio->vl_number; i++)
   4.658 +        s->lapic_info[i] = vio->vl_info + i;
   4.659 +#endif
   4.660 +
   4.661 +}
   4.662 +
   4.663 +void
   4.664 +ioapic_intack(IOAPICState *s)
   4.665 +{
   4.666 +#ifdef IOAPIC_DEBUG
   4.667 +    if (!s){
   4.668 +        fprintf(logfile, "ioapic_intack null parameter\n");
   4.669 +        return;
   4.670 +    }
   4.671 +#endif
   4.672 +    if (!s) s->INTR = 0;
   4.673 +}
   4.674 +
   4.675 +int
   4.676 +ioapic_has_intr()
   4.677 +{
   4.678 +    return ioapic->INTR;
   4.679 +}
   4.680 +
   4.681 +void
   4.682 +do_ioapic()
   4.683 +{
   4.684 +    service_ioapic(ioapic);
   4.685 +    ioapic_intack(ioapic);
   4.686 +}
   4.687 +
   4.688 +IOAPICState *
   4.689 +IOAPICInit( )
   4.690 +{
   4.691 +    IOAPICState *s;
   4.692 +
   4.693 +    s = qemu_mallocz(sizeof(IOAPICState));
   4.694 +    if (!s){
   4.695 +        fprintf(logfile, "IOAPICInit: malloc failed\n");
   4.696 +        return NULL;
   4.697 +    }
   4.698 +
   4.699 +    IOAPICReset(s);
   4.700 +    ioapic_init_apic_info(s);
   4.701 +    register_savevm("ioapic", 0, 1, ioapic_save, ioapic_load, s);
   4.702 +    /* Remove after GFW ready */
   4.703 +    ioapic_update_config(s, 0xfec00000, 1);
   4.704 +
   4.705 +    ioapic = s;
   4.706 +    return s;
   4.707 +}
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/tools/ioemu/hw/ioapic.h	Thu Jun 30 08:09:40 2005 +0000
     5.3 @@ -0,0 +1,128 @@
     5.4 +/////////////////////////////////////////////////////////////////////////
     5.5 +//
     5.6 +//  Copyright (C) 2001  MandrakeSoft S.A.
     5.7 +//
     5.8 +//    MandrakeSoft S.A.
     5.9 +//    43, rue d'Aboukir
    5.10 +//    75002 Paris - France
    5.11 +//    http://www.linux-mandrake.com/
    5.12 +//    http://www.mandrakesoft.com/
    5.13 +//
    5.14 +//  This library is free software; you can redistribute it and/or
    5.15 +//  modify it under the terms of the GNU Lesser General Public
    5.16 +//  License as published by the Free Software Foundation; either
    5.17 +//  version 2 of the License, or (at your option) any later version.
    5.18 +//
    5.19 +//  This library is distributed in the hope that it will be useful,
    5.20 +//  but WITHOUT ANY WARRANTY; without even the implied warranty of
    5.21 +//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    5.22 +//  Lesser General Public License for more details.
    5.23 +//
    5.24 +//  You should have received a copy of the GNU Lesser General Public
    5.25 +//  License along with this library; if not, write to the Free Software
    5.26 +//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
    5.27 +//
    5.28 +
    5.29 +#ifndef __IOAPIC_H
    5.30 +#define __IOAPIC_H
    5.31 +
    5.32 +#include "xc.h"
    5.33 +#include <io/ioreq.h>
    5.34 +#include <io/vmx_vlapic.h>
    5.35 +
    5.36 +#define IOAPIC_NUM_PINS 24
    5.37 +#define IOAPIC_VERSION_ID 0x11
    5.38 +#define IOAPIC_LEVEL_TRIGGER 1
    5.39 +#define APIC_DM_FIXED	0
    5.40 +#define APIC_DM_LOWPRI	1
    5.41 +
    5.42 +
    5.43 +
    5.44 +#ifdef CONFIG_SMP
    5.45 +#define LOCK_PREFIX "lock ; "
    5.46 +#else
    5.47 +#define LOCK_PREFIX ""
    5.48 +#endif
    5.49 +
    5.50 +#ifdef __I386__
    5.51 +#define __OS "q" 
    5.52 +#define __OP "r" 
    5.53 +#else
    5.54 +#define __OS "l"  /* Operation Suffix */
    5.55 +#define __OP "e"  /* Operand Prefix */
    5.56 +#endif
    5.57 +
    5.58 +#define ADDR (*(volatile long *) addr)
    5.59 +#if 0
    5.60 +#endif
    5.61 +extern void *shared_page;
    5.62 +extern FILE *logfile;
    5.63 +#ifdef __BIGENDIAN__
    5.64 +typedef union RedirStatus
    5.65 +{
    5.66 +    uint64_t value;
    5.67 +    struct {
    5.68 +        uint8_t dest_id;
    5.69 +        uint8_t reserved[4];
    5.70 +        uint8_t reserve:7;
    5.71 +        uint8_t mask:1;         /* interrupt mask*/
    5.72 +        uint8_t trigmod:1;
    5.73 +        uint8_t remoteirr:1;
    5.74 +        uint8_t polarity:1;
    5.75 +        uint8_t delivestatus:1;
    5.76 +        uint8_t destmode:1;
    5.77 +        uint8_t deliver_mode:3;
    5.78 +        uint8_t vector;
    5.79 +    }RedirForm;
    5.80 +}RedirStatus;
    5.81 +#else
    5.82 +typedef union RedirStatus
    5.83 +{
    5.84 +    uint64_t value;
    5.85 +    struct {
    5.86 +        uint8_t vector;
    5.87 +        uint8_t deliver_mode:3;
    5.88 +        uint8_t destmode:1;
    5.89 +        uint8_t delivestatus:1;
    5.90 +        uint8_t polarity:1;
    5.91 +        uint8_t remoteirr:1;
    5.92 +        uint8_t trigmod:1;
    5.93 +        uint8_t mask:1;         /* interrupt mask*/
    5.94 +        uint8_t reserve:7;
    5.95 +        uint8_t reserved[4];
    5.96 +        uint8_t dest_id;
    5.97 +    }RedirForm;
    5.98 +}RedirStatus;
    5.99 +#endif
   5.100 +/*
   5.101 + * IOAPICState stands for a instance of a IOAPIC
   5.102 + */
   5.103 +
   5.104 +/* FIXME tmp before working with Local APIC */
   5.105 +#define IOAPIC_MEM_LENGTH 0x100
   5.106 +#define IOAPIC_ENABLE_MASK 0x0
   5.107 +#define IOAPIC_ENABLE_FLAG (1 << IOAPIC_ENABLE_MASK)
   5.108 +#define MAX_LAPIC_NUM 32
   5.109 +
   5.110 +struct IOAPICState{
   5.111 +    uint32_t INTR;
   5.112 +    uint32_t id;
   5.113 +    uint32_t arb_id;
   5.114 +    uint32_t  flags;
   5.115 +    unsigned long base_address;
   5.116 +    uint32_t irr;
   5.117 +    uint32_t isr;           /* This is used for level trigger */
   5.118 +    uint8_t  vector_irr[256];
   5.119 +    RedirStatus redirtbl[IOAPIC_NUM_PINS];
   5.120 +    uint32_t ioregsel;
   5.121 +    uint32_t lapic_count;
   5.122 +    vlapic_info *lapic_info[MAX_LAPIC_NUM];
   5.123 +};
   5.124 +#define IOAPIC_REG_APIC_ID 0x0
   5.125 +#define IOAPIC_REG_VERSION 0x1
   5.126 +#define IOAPIC_REG_ARB_ID  0x2
   5.127 +#define IOAPICEnabled(s) (s->flags & IOAPIC_ENABLE_FLAG)
   5.128 +
   5.129 +typedef struct IOAPICState IOAPICState;
   5.130 +
   5.131 +#endif
     6.1 --- a/tools/ioemu/hw/pc.c	Thu Jun 30 08:09:23 2005 +0000
     6.2 +++ b/tools/ioemu/hw/pc.c	Thu Jun 30 08:09:40 2005 +0000
     6.3 @@ -543,6 +543,9 @@ void pc_init(int ram_size, int vga_ram_s
     6.4              pci_ne2000_init(pci_bus, &nd_table[i]);
     6.5          }
     6.6          pci_piix3_ide_init(pci_bus, bs_table);
     6.7 +#ifdef APIC_SUPPORT
     6.8 +        IOAPICInit();
     6.9 +#endif
    6.10      } else {
    6.11          nb_nics1 = nb_nics;
    6.12          if (nb_nics1 > NE2000_NB_MAX)
     7.1 --- a/tools/ioemu/hw/pci.c	Thu Jun 30 08:09:23 2005 +0000
     7.2 +++ b/tools/ioemu/hw/pci.c	Thu Jun 30 08:09:40 2005 +0000
     7.3 @@ -53,6 +53,7 @@ target_phys_addr_t pci_mem_base;
     7.4  static int pci_irq_index;
     7.5  static uint32_t pci_irq_levels[4][PCI_IRQ_WORDS];
     7.6  static PCIBus *first_bus;
     7.7 +extern FILE *logfile;
     7.8  
     7.9  static PCIBus *pci_register_bus(void)
    7.10  {
    7.11 @@ -569,13 +570,26 @@ static void piix3_reset(PIIX3State *d)
    7.12      pci_conf[0xae] = 0x00;
    7.13  }
    7.14  
    7.15 +#define PIIX_CONFIG_XBCS 0x4f
    7.16 +void piix3_write_config(PCIDevice *d,
    7.17 +  uint32_t address, uint32_t val, int len)
    7.18 +{
    7.19 +    if ((PIIX3State *)d != piix3_state){
    7.20 +        fprintf(logfile, "piix3_write_config: error PCIDevice\n");
    7.21 +        return;
    7.22 +    }
    7.23 +
    7.24 +    pci_default_write_config(d, address, val, len);
    7.25 +}
    7.26 +
    7.27 +
    7.28  void piix3_init(PCIBus *bus)
    7.29  {
    7.30      PIIX3State *d;
    7.31      uint8_t *pci_conf;
    7.32  
    7.33      d = (PIIX3State *)pci_register_device(bus, "PIIX3", sizeof(PIIX3State),
    7.34 -                                          -1, NULL, NULL);
    7.35 +                                          -1, NULL, piix3_write_config);
    7.36      register_savevm("PIIX3", 0, 1, generic_pci_save, generic_pci_load, d);
    7.37  
    7.38      piix3_state = d;
     8.1 --- a/tools/ioemu/target-i386-dm/Makefile	Thu Jun 30 08:09:23 2005 +0000
     8.2 +++ b/tools/ioemu/target-i386-dm/Makefile	Thu Jun 30 08:09:40 2005 +0000
     8.3 @@ -188,7 +188,7 @@ endif
     8.4  
     8.5  #########################################################
     8.6  
     8.7 -DEFINES+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
     8.8 +DEFINES+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -DAPIC_SUPPORT
     8.9  LIBS+=-lm -L../../libxc -lxc
    8.10  ifndef CONFIG_USER_ONLY
    8.11  LIBS+=-lz
    8.12 @@ -246,6 +246,7 @@ endif
    8.13  # must use static linking to avoid leaving stuff in virtual address space
    8.14  VL_OBJS=vl.o exec.o monitor.o osdep.o block.o readline.o pci.o console.o 
    8.15  VL_OBJS+=block-cow.o block-qcow.o block-vmdk.o block-cloop.o aes.o
    8.16 +VL_OBJS+=ioapic.o
    8.17  #VL_OBJS+= block-cloop.o
    8.18  
    8.19  SOUND_HW = sb16.o
     9.1 --- a/tools/ioemu/target-i386-dm/helper2.c	Thu Jun 30 08:09:23 2005 +0000
     9.2 +++ b/tools/ioemu/target-i386-dm/helper2.c	Thu Jun 30 08:09:40 2005 +0000
     9.3 @@ -320,7 +320,7 @@ do_interrupt(CPUState *env, int vector)
     9.4  
     9.5  	// Send a message on the event channel. Add the vector to the shared mem
     9.6  	// page.
     9.7 -	intr = &(shared_page->vcpu_iodata[0].vp_intr[0]);
     9.8 +	intr = &(shared_page->sp_global.pic_intr[0]);
     9.9  	atomic_set_bit(vector, intr);
    9.10          if (loglevel & CPU_LOG_INT)
    9.11                  fprintf(logfile, "injecting vector: %x\n", vector);
    9.12 @@ -345,11 +345,11 @@ int main_loop(void)
    9.13  	FD_ZERO(&rfds);
    9.14  
    9.15  	while (1) {
    9.16 -            if (vm_running) {
    9.17 -                if (shutdown_requested) {
    9.18 -                    break;
    9.19 +                if (vm_running) {
    9.20 +                    if (shutdown_requested) {
    9.21 +                        break;
    9.22 +                    }
    9.23                  }
    9.24 -            }
    9.25  
    9.26  		/* Wait up to one seconds. */
    9.27  		tv.tv_sec = 0;
    9.28 @@ -370,14 +370,19 @@ int main_loop(void)
    9.29  #endif
    9.30  
    9.31  		main_loop_wait(0);
    9.32 -
    9.33 +#ifdef APIC_SUPPORT
    9.34 +		ioapic_update_EOI();
    9.35 +#endif
    9.36  		cpu_timer_handler(env);
    9.37  		if (env->interrupt_request & CPU_INTERRUPT_HARD) {
    9.38                          env->interrupt_request &= ~CPU_INTERRUPT_HARD;
    9.39  			vector = cpu_get_pic_interrupt(env); 
    9.40  			do_interrupt(env, vector);
    9.41  		}
    9.42 -
    9.43 +#ifdef APIC_SUPPORT
    9.44 +		if (ioapic_has_intr())
    9.45 +                    do_ioapic();
    9.46 +#endif
    9.47  		if (env->send_event) {
    9.48  			int ret;
    9.49  			ret = xc_evtchn_send(xc_handle, ioreq_port);
    10.1 --- a/xen/arch/x86/vmx_intercept.c	Thu Jun 30 08:09:23 2005 +0000
    10.2 +++ b/xen/arch/x86/vmx_intercept.c	Thu Jun 30 08:09:40 2005 +0000
    10.3 @@ -213,7 +213,8 @@ void vmx_hooks_assist(struct vcpu *d)
    10.4  {
    10.5      vcpu_iodata_t * vio = get_vio(d->domain, d->vcpu_id);
    10.6      ioreq_t *p = &vio->vp_ioreq;
    10.7 -    unsigned long *intr = &(vio->vp_intr[0]);
    10.8 +    shared_iopage_t *sp = get_sp(d->domain);
    10.9 +    u64 *intr = &(sp->sp_global.pic_intr[0]);
   10.10      struct vmx_virpit_t *vpit = &(d->domain->arch.vmx_platform.vmx_pit);
   10.11      int rw_mode;
   10.12  
    11.1 --- a/xen/arch/x86/vmx_io.c	Thu Jun 30 08:09:23 2005 +0000
    11.2 +++ b/xen/arch/x86/vmx_io.c	Thu Jun 30 08:09:40 2005 +0000
    11.3 @@ -22,6 +22,7 @@
    11.4  #include <xen/lib.h>
    11.5  #include <xen/errno.h>
    11.6  #include <xen/trace.h>
    11.7 +#include <xen/event.h>
    11.8  
    11.9  #include <asm/current.h>
   11.10  #include <asm/cpufeature.h>
   11.11 @@ -29,10 +30,12 @@
   11.12  #include <asm/msr.h>
   11.13  #include <asm/vmx.h>
   11.14  #include <asm/vmx_vmcs.h>
   11.15 -#include <xen/event.h>
   11.16 -#include <public/io/ioreq.h>
   11.17  #include <asm/vmx_platform.h>
   11.18  #include <asm/vmx_virpit.h>
   11.19 +#include <asm/apic.h>
   11.20 +
   11.21 +#include <public/io/ioreq.h>
   11.22 +#include <public/io/vmx_vlapic.h>
   11.23  
   11.24  #ifdef CONFIG_VMX
   11.25  #if defined (__i386__)
   11.26 @@ -515,38 +518,100 @@ static __inline__ int find_highest_irq(u
   11.27      return __fls(pintr[0]);
   11.28  }
   11.29  
   11.30 +#define BSP_CPU(d)    (!(d->vcpu_id))
   11.31 +static inline void clear_extint(struct vcpu *v)
   11.32 +{
   11.33 +    global_iodata_t *spg;
   11.34 +    int i;
   11.35 +    spg = &get_sp(v->domain)->sp_global;
   11.36 +
   11.37 +    for(i = 0; i < INTR_LEN; i++)
   11.38 +        spg->pic_intr[i] = 0;
   11.39 +}
   11.40 +
   11.41 +static inline void clear_highest_bit(struct vcpu *v, int vector)
   11.42 +{
   11.43 +    global_iodata_t *spg;
   11.44 +
   11.45 +    spg = &get_sp(v->domain)->sp_global;
   11.46 +
   11.47 +    clear_bit(vector, &spg->pic_intr[0]);
   11.48 +}
   11.49 +
   11.50 +static inline int find_highest_pic_irq(struct vcpu *v)
   11.51 +{
   11.52 +    u64 intr[INTR_LEN];
   11.53 +    global_iodata_t *spg;
   11.54 +    int i;
   11.55 +
   11.56 +    if(!BSP_CPU(v))
   11.57 +        return -1;
   11.58 +
   11.59 +    spg = &get_sp(v->domain)->sp_global;
   11.60 +
   11.61 +    for(i = 0; i < INTR_LEN; i++){
   11.62 +        intr[i] = spg->pic_intr[i] & ~spg->pic_mask[i];
   11.63 +    }
   11.64 +
   11.65 +    return find_highest_irq((u32 *)&intr[0]);
   11.66 +}
   11.67 +
   11.68  /*
   11.69   * Return 0-255 for pending irq.
   11.70   *        -1 when no pending.
   11.71   */
   11.72 -static inline int find_highest_pending_irq(struct vcpu *d)
   11.73 +static inline int find_highest_pending_irq(struct vcpu *v, int *type)
   11.74  {
   11.75 -    vcpu_iodata_t *vio;
   11.76 -
   11.77 -    vio = get_vio(d->domain, d->vcpu_id);
   11.78 -
   11.79 -    if (vio == 0) {
   11.80 -        VMX_DBG_LOG(DBG_LEVEL_1, 
   11.81 -                    "bad shared page: %lx", (unsigned long) vio);
   11.82 -        domain_crash_synchronous();
   11.83 +    int result = -1;
   11.84 +    if ((result = find_highest_pic_irq(v)) != -1){
   11.85 +        *type = VLAPIC_DELIV_MODE_EXT;
   11.86 +        return result;
   11.87      }
   11.88 -        
   11.89 -    return find_highest_irq((unsigned int *)&vio->vp_intr[0]);
   11.90 +    return result;
   11.91  }
   11.92  
   11.93 -static inline void clear_highest_bit(struct vcpu *d, int vector)
   11.94 +static inline void
   11.95 +interrupt_post_injection(struct vcpu * v, int vector, int type)
   11.96  {
   11.97 -    vcpu_iodata_t *vio;
   11.98 +    struct vmx_virpit_t *vpit = &(v->domain->arch.vmx_platform.vmx_pit);
   11.99 +    switch(type)
  11.100 +    {
  11.101 +        case VLAPIC_DELIV_MODE_EXT:
  11.102 +            if (vpit->pending_intr_nr && vector == vpit->vector)
  11.103 +                vpit->pending_intr_nr--;
  11.104 +            else
  11.105 +                clear_highest_bit(v, vector);
  11.106  
  11.107 -    vio = get_vio(d->domain, d->vcpu_id);
  11.108 +            if (vector == vpit->vector && !vpit->first_injected){
  11.109 +                vpit->first_injected = 1;
  11.110 +                vpit->pending_intr_nr = 0;
  11.111 +            }
  11.112 +            if (vector == vpit->vector)
  11.113 +                vpit->inject_point = NOW();
  11.114 +            break;
  11.115  
  11.116 -    if (vio == 0) {
  11.117 -        VMX_DBG_LOG(DBG_LEVEL_1, 
  11.118 -                    "bad shared page: %lx", (unsigned long) vio);
  11.119 -        domain_crash_synchronous();
  11.120 +        default:
  11.121 +            printk("Not support interrupt type\n");
  11.122 +            break;
  11.123      }
  11.124 -        
  11.125 -    clear_bit(vector, &vio->vp_intr[0]);
  11.126 +}
  11.127 +
  11.128 +static inline void
  11.129 +enable_irq_window(unsigned long cpu_exec_control)
  11.130 +{
  11.131 +    if (!(cpu_exec_control & CPU_BASED_VIRTUAL_INTR_PENDING)) {
  11.132 +        cpu_exec_control |= CPU_BASED_VIRTUAL_INTR_PENDING;
  11.133 +        __vmwrite(CPU_BASED_VM_EXEC_CONTROL, cpu_exec_control);
  11.134 +    }
  11.135 +}
  11.136 +
  11.137 +static inline void
  11.138 +disable_irq_window(unsigned long cpu_exec_control)
  11.139 +{
  11.140 +    if ( cpu_exec_control & CPU_BASED_VIRTUAL_INTR_PENDING ) {
  11.141 +        cpu_exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING;
  11.142 +        __vmwrite(CPU_BASED_VM_EXEC_CONTROL, cpu_exec_control);
  11.143 +    }
  11.144  }
  11.145  
  11.146  static inline int irq_masked(unsigned long eflags)
  11.147 @@ -554,50 +619,68 @@ static inline int irq_masked(unsigned lo
  11.148      return ((eflags & X86_EFLAGS_IF) == 0);
  11.149  }
  11.150  
  11.151 -void vmx_intr_assist(struct vcpu *d) 
  11.152 +void vmx_intr_assist(struct vcpu *v) 
  11.153  {
  11.154 -    int highest_vector = find_highest_pending_irq(d);
  11.155 -    unsigned long intr_fields, eflags;
  11.156 -    struct vmx_virpit_t *vpit = &(d->domain->arch.vmx_platform.vmx_pit);
  11.157 +    int intr_type;
  11.158 +    int highest_vector = find_highest_pending_irq(v, &intr_type);
  11.159 +    unsigned long intr_fields, eflags, interruptibility, cpu_exec_control;
  11.160  
  11.161 -    if (highest_vector == -1)
  11.162 -        return;
  11.163 +    __vmread(CPU_BASED_VM_EXEC_CONTROL, &cpu_exec_control);
  11.164  
  11.165 -    __vmread(VM_ENTRY_INTR_INFO_FIELD, &intr_fields);
  11.166 -    if (intr_fields & INTR_INFO_VALID_MASK) {
  11.167 -        VMX_DBG_LOG(DBG_LEVEL_1, "vmx_intr_assist: intr_fields: %lx",
  11.168 -                    intr_fields);
  11.169 +    if (highest_vector == -1) {
  11.170 +        disable_irq_window(cpu_exec_control);
  11.171          return;
  11.172      }
  11.173  
  11.174 -    __vmread(GUEST_RFLAGS, &eflags);
  11.175 -    if (irq_masked(eflags)) {
  11.176 -        VMX_DBG_LOG(DBG_LEVEL_1, "guesting pending: %x, eflags: %lx",
  11.177 -                    highest_vector, eflags);
  11.178 -        return;
  11.179 -    }
  11.180 -        
  11.181 -    if (vpit->pending_intr_nr && highest_vector == vpit->vector)
  11.182 -        vpit->pending_intr_nr--;
  11.183 -    else
  11.184 -        clear_highest_bit(d, highest_vector); 
  11.185 +     __vmread(VM_ENTRY_INTR_INFO_FIELD, &intr_fields);
  11.186 +
  11.187 +     if (intr_fields & INTR_INFO_VALID_MASK) {
  11.188 +         VMX_DBG_LOG(DBG_LEVEL_1, "vmx_intr_assist: intr_fields: %lx",
  11.189 +           intr_fields);
  11.190 +         return;
  11.191 +     }
  11.192 +
  11.193 +     __vmread(GUEST_INTERRUPTIBILITY_INFO, &interruptibility);
  11.194 +
  11.195 +     if (interruptibility) {
  11.196 +         enable_irq_window(cpu_exec_control);
  11.197 +         VMX_DBG_LOG(DBG_LEVEL_1, "guesting pending: %x, interruptibility: %lx",
  11.198 +                     highest_vector, interruptibility);
  11.199 +         return;
  11.200 +     }
  11.201 +
  11.202 +     __vmread(GUEST_RFLAGS, &eflags);
  11.203  
  11.204 -    /* close the window between guest PIT initialization and sti */
  11.205 -    if (highest_vector == vpit->vector && !vpit->first_injected){
  11.206 -        vpit->first_injected = 1;
  11.207 -        vpit->pending_intr_nr = 0;
  11.208 -    }
  11.209 +     switch (intr_type) {
  11.210 +         case VLAPIC_DELIV_MODE_EXT:
  11.211 +             if (irq_masked(eflags)) {
  11.212 +                 enable_irq_window(cpu_exec_control);
  11.213 +                 VMX_DBG_LOG(DBG_LEVEL_1, "guesting pending: %x, eflags: %lx",
  11.214 +                             highest_vector, eflags);
  11.215 +                 return;
  11.216 +             }
  11.217 +
  11.218 +             intr_fields = (INTR_INFO_VALID_MASK | INTR_TYPE_EXT_INTR 
  11.219 +                            | highest_vector);
  11.220 +             __vmwrite(VM_ENTRY_INTR_INFO_FIELD, intr_fields);
  11.221 +             __vmwrite(GUEST_INTERRUPTIBILITY_INFO, 0);
  11.222  
  11.223 -    intr_fields = (INTR_INFO_VALID_MASK | INTR_TYPE_EXT_INTR | highest_vector);
  11.224 -    __vmwrite(VM_ENTRY_INTR_INFO_FIELD, intr_fields);
  11.225 -
  11.226 -    __vmwrite(GUEST_INTERRUPTIBILITY_INFO, 0);
  11.227 +             TRACE_3D(TRC_VMX_INT, v->domain->domain_id, highest_vector, 0);
  11.228 +             break;
  11.229 +         case VLAPIC_DELIV_MODE_FIXED:
  11.230 +         case VLAPIC_DELIV_MODE_LPRI:
  11.231 +         case VLAPIC_DELIV_MODE_SMI:
  11.232 +         case VLAPIC_DELIV_MODE_NMI:
  11.233 +         case VLAPIC_DELIV_MODE_INIT:
  11.234 +         case VLAPIC_DELIV_MODE_STARTUP:
  11.235 +         default:
  11.236 +             printk("Unsupported interrupt type\n");
  11.237 +             BUG();
  11.238 +             break;
  11.239 +     }
  11.240  
  11.241 -    TRACE_3D(TRC_VMX_INT, d->domain->domain_id, highest_vector, 0);
  11.242 -    if (highest_vector == vpit->vector)
  11.243 -        vpit->inject_point = NOW();
  11.244 -
  11.245 -    return;
  11.246 +     interrupt_post_injection(v, highest_vector, intr_type);
  11.247 +     return;
  11.248  }
  11.249  
  11.250  void vmx_do_resume(struct vcpu *d) 
    12.1 --- a/xen/arch/x86/vmx_vmcs.c	Thu Jun 30 08:09:23 2005 +0000
    12.2 +++ b/xen/arch/x86/vmx_vmcs.c	Thu Jun 30 08:09:40 2005 +0000
    12.3 @@ -153,6 +153,8 @@ int vmx_setup_platform(struct vcpu *d, s
    12.4      p = map_domain_page(mpfn);
    12.5      d->domain->arch.vmx_platform.shared_page_va = (unsigned long)p;
    12.6  
    12.7 +   VMX_DBG_LOG(DBG_LEVEL_1, "eport: %x\n", iopacket_port(d->domain));
    12.8 +
    12.9     clear_bit(iopacket_port(d->domain), 
   12.10               &d->domain->shared_info->evtchn_mask[0]);
   12.11  
    13.1 --- a/xen/include/asm-x86/vmx.h	Thu Jun 30 08:09:23 2005 +0000
    13.2 +++ b/xen/include/asm-x86/vmx.h	Thu Jun 30 08:09:40 2005 +0000
    13.3 @@ -339,14 +339,19 @@ static inline int vmx_paging_enabled(str
    13.4      return (cr0 & X86_CR0_PE) && (cr0 & X86_CR0_PG);
    13.5  }
    13.6  
    13.7 +static inline shared_iopage_t *get_sp(struct domain *d)
    13.8 +{
    13.9 +    return (shared_iopage_t *) d->arch.vmx_platform.shared_page_va;
   13.10 +}
   13.11 +
   13.12  static inline vcpu_iodata_t *get_vio(struct domain *d, unsigned long cpu)
   13.13  {
   13.14 -    return &((shared_iopage_t *) d->arch.vmx_platform.shared_page_va)->vcpu_iodata[cpu];
   13.15 +    return &get_sp(d)->vcpu_iodata[cpu];
   13.16  }
   13.17  
   13.18  static inline int iopacket_port(struct domain *d)
   13.19  {
   13.20 -    return ((shared_iopage_t *) d->arch.vmx_platform.shared_page_va)->sp_global.eport;
   13.21 +    return get_sp(d)->sp_global.eport;
   13.22  }
   13.23  
   13.24  #endif /* __ASM_X86_VMX_H__ */
    14.1 --- a/xen/include/asm-x86/vmx_virpit.h	Thu Jun 30 08:09:23 2005 +0000
    14.2 +++ b/xen/include/asm-x86/vmx_virpit.h	Thu Jun 30 08:09:40 2005 +0000
    14.3 @@ -20,7 +20,7 @@ struct vmx_virpit_t {
    14.4      int vector;				/* the pit irq vector */
    14.5      unsigned int period;		/* the frequency. e.g. 10ms*/
    14.6      unsigned int channel;		/* the pit channel, counter 0~2 */
    14.7 -    unsigned long *intr_bitmap;
    14.8 +    u64  *intr_bitmap;
    14.9      unsigned int pending_intr_nr;	/* the couner for pending timer interrupts */
   14.10      unsigned long long inject_point;	/* the time inject virt intr */
   14.11      struct ac_timer pit_timer;		/* periodic timer for mode 2*/
    15.1 --- a/xen/include/public/io/ioreq.h	Thu Jun 30 08:09:23 2005 +0000
    15.2 +++ b/xen/include/public/io/ioreq.h	Thu Jun 30 08:09:40 2005 +0000
    15.3 @@ -49,14 +49,11 @@ typedef struct {
    15.4  
    15.5  #define MAX_VECTOR    256
    15.6  #define BITS_PER_BYTE   8
    15.7 -#define INTR_LEN        (MAX_VECTOR/(BITS_PER_BYTE * sizeof(unsigned long)))
    15.8 +#define INTR_LEN        (MAX_VECTOR/(BITS_PER_BYTE * sizeof(u64)))
    15.9  
   15.10 -/* We only track the master PIC state here */
   15.11  typedef struct {
   15.12 -    uint16_t irr; /* interrupt request register */
   15.13 -    uint16_t imr; /* interrupt mask register */
   15.14 -    uint16_t isr; /* interrupt service register */
   15.15 -
   15.16 +    u64   pic_intr[INTR_LEN];
   15.17 +    u64   pic_mask[INTR_LEN];
   15.18      int     eport; /* Event channel port */
   15.19  } global_iodata_t;
   15.20  
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/xen/include/public/io/vmx_vlapic.h	Thu Jun 30 08:09:40 2005 +0000
    16.3 @@ -0,0 +1,57 @@
    16.4 +#ifndef _VMX_VLAPIC_H
    16.5 +#define _VMX_VLAPIC_H
    16.6 +
    16.7 +/*
    16.8 +   We extended one bit for PIC type
    16.9 + */
   16.10 +#define VLAPIC_DELIV_MODE_FIXED          0x0
   16.11 +#define VLAPIC_DELIV_MODE_LPRI           0x1
   16.12 +#define VLAPIC_DELIV_MODE_SMI            0x2
   16.13 +#define VLAPIC_DELIV_MODE_NMI            0x4
   16.14 +#define VLAPIC_DELIV_MODE_INIT           0x5
   16.15 +#define VLAPIC_DELIV_MODE_STARTUP        0x6
   16.16 +#define VLAPIC_DELIV_MODE_EXT            0x7
   16.17 +#define VLAPIC_DELIV_MODE_MASK            0x8
   16.18 +
   16.19 +#define VLAPIC_MSG_LEVEL                4
   16.20 +
   16.21 +#define INTR_EXT   0
   16.22 +#define INTR_APIC   1
   16.23 +#define INTR_LAPIC  2
   16.24 +
   16.25 +#define VL_STATE_EOI    1
   16.26 +#define VL_STATE_EXT_LOCK   2
   16.27 +#define VL_STATE_MSG_LOCK   3
   16.28 +#define VL_STATE_EOI_LOCK   3
   16.29 +
   16.30 +#define VLOCAL_APIC_MAX_INTS             256
   16.31 +#define VLAPIC_INT_COUNT                (VLOCAL_APIC_MAX_INTS/(BITS_PER_BYTE * sizeof(u64)))
   16.32 +#define VLAPIC_INT_COUNT_32             (VLOCAL_APIC_MAX_INTS/(BITS_PER_BYTE * sizeof(u32)))
   16.33 +
   16.34 +struct vapic_bus_message{
   16.35 +   u8   deliv_mode:4;   /* deliver mode, including fixed, LPRI, etc */
   16.36 +   u8   level:1;        /* level or edge */
   16.37 +   u8   trig_mod:1;    /* assert or disassert */
   16.38 +   u8   reserved:2;
   16.39 +   u8   vector;
   16.40 +};
   16.41 +
   16.42 +typedef struct {
   16.43 +    /* interrupt for PIC and ext type IOAPIC interrupt */
   16.44 +    u64   vl_ext_intr[VLAPIC_INT_COUNT];
   16.45 +    u64   vl_ext_intr_mask[VLAPIC_INT_COUNT];
   16.46 +    u64   vl_apic_intr[VLAPIC_INT_COUNT];
   16.47 +    u64   vl_apic_tmr[VLAPIC_INT_COUNT];
   16.48 +    u64   vl_eoi[VLAPIC_INT_COUNT];
   16.49 +    u32   vl_lapic_id;
   16.50 +    u32   direct_intr;
   16.51 +    u32   vl_apr;
   16.52 +    u32   vl_logical_dest;
   16.53 +    u32   vl_dest_format;
   16.54 +    u32   vl_arb_id;
   16.55 +    u32   vl_state;
   16.56 +    u32   apic_msg_count;
   16.57 +    struct vapic_bus_message  vl_apic_msg[24];
   16.58 +} vlapic_info;
   16.59 +
   16.60 +#endif /* _VMX_VLAPIC_H_ */