ia64/xen-unstable

changeset 12670:0705db48d23c

[IA64] Change to new interrupt deliver mechanism.

Signed-off-by: Anthony Xu <anthony.xu@intel.com>
author awilliam@xenbuild.aw
date Fri Dec 01 11:40:57 2006 -0700 (2006-12-01)
parents 76d379e3f1d7
children 6fdbf173142d
files linux-2.6-xen-sparse/arch/ia64/xen/xcom_privcmd.c tools/ioemu/Makefile.target xen/arch/ia64/vmx/viosapic.c xen/arch/ia64/vmx/vmx_hypercall.c xen/include/asm-ia64/viosapic.h
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/ia64/xen/xcom_privcmd.c	Fri Dec 01 11:12:00 2006 -0700
     1.2 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/xcom_privcmd.c	Fri Dec 01 11:40:57 2006 -0700
     1.3 @@ -579,9 +579,16 @@ xencomm_privcmd_hvm_op(privcmd_hypercall
     1.4  	case HVMOP_set_param:
     1.5  		argsize = sizeof(xen_hvm_param_t);
     1.6  		break;
     1.7 -	case HVMOP_set_irq_level:
     1.8 -		argsize = sizeof(xen_hvm_set_irq_level_t);
     1.9 +	case HVMOP_set_pci_intx_level:
    1.10 +		argsize = sizeof(xen_hvm_set_pci_intx_level_t);
    1.11  		break;
    1.12 +	case HVMOP_set_isa_irq_level:
    1.13 +		argsize = sizeof(xen_hvm_set_isa_irq_level_t);
    1.14 +		break;
    1.15 +	case HVMOP_set_pci_link_route:
    1.16 +		argsize = sizeof(xen_hvm_set_pci_link_route_t);
    1.17 +		break;
    1.18 +
    1.19  	default:
    1.20  		printk("%s: unknown HVMOP %d\n", __func__, cmd);
    1.21  		return -EINVAL;
     2.1 --- a/tools/ioemu/Makefile.target	Fri Dec 01 11:12:00 2006 -0700
     2.2 +++ b/tools/ioemu/Makefile.target	Fri Dec 01 11:40:57 2006 -0700
     2.3 @@ -296,7 +296,7 @@ endif
     2.4  
     2.5  # qemu-dm objects
     2.6  ifeq ($(ARCH),ia64)
     2.7 -LIBOBJS=helper2.o exec-dm.o i8259-dm.o
     2.8 +LIBOBJS=helper2.o exec-dm.o i8259-dm.o piix_pci-dm.o
     2.9  else
    2.10  LIBOBJS=helper2.o exec-dm.o i8259-dm.o rtc-dm.o piix_pci-dm.o
    2.11  endif
    2.12 @@ -360,7 +360,7 @@ ifeq ($(TARGET_BASE_ARCH), i386)
    2.13  # Hardware support
    2.14  VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
    2.15  ifeq ($(ARCH),ia64)
    2.16 -VL_OBJS+= fdc.o mc146818rtc.o serial.o pc.o piix_pci.o
    2.17 +VL_OBJS+= fdc.o mc146818rtc.o serial.o pc.o
    2.18  else
    2.19  VL_OBJS+= fdc.o serial.o pc.o
    2.20  endif
     3.1 --- a/xen/arch/ia64/vmx/viosapic.c	Fri Dec 01 11:12:00 2006 -0700
     3.2 +++ b/xen/arch/ia64/vmx/viosapic.c	Fri Dec 01 11:40:57 2006 -0700
     3.3 @@ -70,9 +70,12 @@ static void viosapic_deliver(struct vios
     3.4  
     3.5  static int iosapic_get_highest_irq(struct viosapic *viosapic)
     3.6  {
     3.7 -    uint32_t irqs = viosapic->irr | viosapic->irr_xen;
     3.8 -    irqs &= ~viosapic->isr & ~viosapic->imr;
     3.9 -    return fls(irqs) - 1;
    3.10 +    uint64_t irqs = viosapic->irr & ~viosapic->isr ;
    3.11 +   
    3.12 +    if (irqs >> 32)
    3.13 +        return (fls(irqs >> 32) - 1 + 32);
    3.14 +    else
    3.15 +        return fls(irqs) - 1;
    3.16  }
    3.17  
    3.18  
    3.19 @@ -95,14 +98,12 @@ static void service_iosapic(struct viosa
    3.20  
    3.21      while ( (irq = iosapic_get_highest_irq(viosapic)) != -1 )
    3.22      {
    3.23 -        if ( !test_bit(irq, &viosapic->imr) )
    3.24 -            viosapic_deliver(viosapic, irq);
    3.25 +        viosapic_deliver(viosapic, irq);
    3.26  
    3.27          if ( viosapic->redirtbl[irq].trig_mode == SAPIC_LEVEL )
    3.28 -            viosapic->isr |= (1 << irq);
    3.29 +            viosapic->isr |= (1UL << irq);
    3.30  
    3.31 -        viosapic->irr &= ~(1 << irq);
    3.32 -        viosapic->irr_xen &= ~(1 << irq);
    3.33 +        viosapic->irr &= ~(1UL << irq);
    3.34      }
    3.35  }
    3.36  
    3.37 @@ -192,15 +193,6 @@ unsigned long viosapic_read(struct vcpu 
    3.38  }
    3.39  
    3.40  
    3.41 -static inline void viosapic_update_imr(struct viosapic *viosapic, int index)
    3.42 -{
    3.43 -    if ( viosapic->redirtbl[index].mask )
    3.44 -        set_bit(index, &viosapic->imr);
    3.45 -    else
    3.46 -        clear_bit(index, &viosapic->imr);
    3.47 -}
    3.48 -
    3.49 -
    3.50  static void viosapic_write_indirect(struct viosapic *viosapic,
    3.51                                      unsigned long addr,
    3.52                                      unsigned long length,
    3.53 @@ -237,7 +229,6 @@ static void viosapic_write_indirect(stru
    3.54                              (val & 0xffffffff);
    3.55          }
    3.56          viosapic->redirtbl[redir_index].bits = redir_content;
    3.57 -        viosapic_update_imr(viosapic, redir_index);
    3.58          break;
    3.59      }
    3.60      } /* switch */
    3.61 @@ -282,39 +273,14 @@ static void viosapic_reset(struct viosap
    3.62      for ( i = 0; i < VIOSAPIC_NUM_PINS; i++ )
    3.63      {
    3.64          viosapic->redirtbl[i].mask = 0x1;
    3.65 -        viosapic_update_imr(viosapic, i);
    3.66      }
    3.67      spin_lock_init(&viosapic->lock);
    3.68  }
    3.69  
    3.70 -
    3.71 -// this is used by VBD/VNIF to inject interrupt for VTI-domain
    3.72 -void viosapic_set_xen_irq(struct domain *d, int irq, int level)
    3.73 -{
    3.74 -    struct viosapic *viosapic = domain_viosapic(d);
    3.75 -
    3.76 -    spin_lock(&viosapic->lock);
    3.77 -    if ( viosapic->redirtbl[irq].mask )
    3.78 -        goto out;
    3.79 -
    3.80 -    if ( viosapic->redirtbl[irq].trig_mode == SAPIC_EDGE)
    3.81 -        gdprintk(XENLOG_WARNING, "Forcing edge triggered APIC irq %d?\n", irq);
    3.82 -
    3.83 -    if ( level )
    3.84 -        viosapic->irr_xen |= 1 << irq;
    3.85 -    else
    3.86 -        viosapic->irr_xen &= ~(1 << irq);
    3.87 -
    3.88 -    service_iosapic(viosapic);
    3.89 -out:
    3.90 -    spin_unlock(&viosapic->lock);
    3.91 -}
    3.92 -
    3.93 -
    3.94  void viosapic_set_irq(struct domain *d, int irq, int level)
    3.95  {
    3.96      struct viosapic *viosapic = domain_viosapic(d);
    3.97 -    uint32_t bit;
    3.98 +    uint64_t bit;
    3.99  
   3.100      spin_lock(&viosapic->lock);
   3.101      if ( (irq < 0) || (irq >= VIOSAPIC_NUM_PINS) )
   3.102 @@ -323,7 +289,7 @@ void viosapic_set_irq(struct domain *d, 
   3.103      if ( viosapic->redirtbl[irq].mask )
   3.104          goto out;
   3.105  
   3.106 -    bit = 1 << irq;
   3.107 +    bit = 1UL << irq;
   3.108      if ( viosapic->redirtbl[irq].trig_mode == SAPIC_LEVEL )
   3.109      {
   3.110          if ( level )
   3.111 @@ -343,6 +309,17 @@ out:
   3.112      spin_unlock(&viosapic->lock);
   3.113  }
   3.114  
   3.115 +#define hvm_pci_intx_gsi(dev, intx)  \
   3.116 +    (((((dev) << 2) + ((dev) >> 3) + (intx)) & 31) + 16)
   3.117 +        
   3.118 +
   3.119 +void viosapic_set_pci_irq(struct domain *d, int device, int intx, int level)
   3.120 +{
   3.121 +    int irq;
   3.122 +    irq = hvm_pci_intx_gsi(device, intx);
   3.123 +
   3.124 +    viosapic_set_irq(d, irq, level);
   3.125 +}
   3.126  
   3.127  void viosapic_init(struct domain *d)
   3.128  {
     4.1 --- a/xen/arch/ia64/vmx/vmx_hypercall.c	Fri Dec 01 11:12:00 2006 -0700
     4.2 +++ b/xen/arch/ia64/vmx/vmx_hypercall.c	Fri Dec 01 11:40:57 2006 -0700
     4.3 @@ -37,6 +37,72 @@
     4.4  #include <asm/vmx.h> 
     4.5  #include <asm/viosapic.h> 
     4.6  
     4.7 +static int hvmop_set_isa_irq_level(
     4.8 +    XEN_GUEST_HANDLE(xen_hvm_set_isa_irq_level_t) uop)
     4.9 +{
    4.10 +    struct xen_hvm_set_isa_irq_level op;
    4.11 +    struct domain *d;
    4.12 +    int rc;
    4.13 +
    4.14 +    if ( copy_from_guest(&op, uop, 1) )
    4.15 +        return -EFAULT;
    4.16 +
    4.17 +    if ( !IS_PRIV(current->domain) )
    4.18 +        return -EPERM;
    4.19 +
    4.20 +    if ( op.isa_irq > 15 )
    4.21 +        return -EINVAL;
    4.22 +
    4.23 +    d = find_domain_by_id(op.domid);
    4.24 +    if ( d == NULL )
    4.25 +        return -ESRCH;
    4.26 +
    4.27 +    rc = -EINVAL;
    4.28 +    if ( !is_hvm_domain(d) )
    4.29 +        goto out;
    4.30 +
    4.31 +    rc = 0;
    4.32 +    viosapic_set_irq(d, op.isa_irq, op.level);
    4.33 +
    4.34 + out:
    4.35 +    put_domain(d);
    4.36 +    return rc;
    4.37 +}
    4.38 +
    4.39 +static int hvmop_set_pci_intx_level(
    4.40 +    XEN_GUEST_HANDLE(xen_hvm_set_pci_intx_level_t) uop)
    4.41 +{
    4.42 +    struct xen_hvm_set_pci_intx_level op;
    4.43 +    struct domain *d;
    4.44 +    int rc;
    4.45 +
    4.46 +    if ( copy_from_guest(&op, uop, 1) )
    4.47 +        return -EFAULT;
    4.48 +
    4.49 +    if ( !IS_PRIV(current->domain) )
    4.50 +        return -EPERM;
    4.51 +
    4.52 +    if ( (op.domain > 0) || (op.bus > 0) || (op.device > 31) || (op.intx > 3) )
    4.53 +        return -EINVAL;
    4.54 +
    4.55 +    d = find_domain_by_id(op.domid);
    4.56 +    if ( d == NULL )
    4.57 +        return -ESRCH;
    4.58 +
    4.59 +    rc = -EINVAL;
    4.60 +    if ( !is_hvm_domain(d) )
    4.61 +        goto out;
    4.62 +
    4.63 +    rc = 0;
    4.64 +    viosapic_set_pci_irq(d, op.device, op.intx, op.level);
    4.65 +
    4.66 + out:
    4.67 +    put_domain(d);
    4.68 +    return rc;
    4.69 +}
    4.70 +
    4.71 +
    4.72 +
    4.73  long
    4.74  do_hvm_op(unsigned long op, XEN_GUEST_HANDLE(void) arg)
    4.75  {
    4.76 @@ -80,30 +146,19 @@ do_hvm_op(unsigned long op, XEN_GUEST_HA
    4.77          break;
    4.78      }
    4.79  
    4.80 -    case HVMOP_set_irq_level:
    4.81 -    {
    4.82 -        struct xen_hvm_set_irq_level op;
    4.83 -        struct domain *d;
    4.84 -
    4.85 -        if (copy_from_guest(&op, arg, 1))
    4.86 -            return -EFAULT;
    4.87 -
    4.88 -        if (!IS_PRIV(current->domain))
    4.89 -            return -EPERM;
    4.90 +    case HVMOP_set_pci_intx_level:
    4.91 +        rc = hvmop_set_pci_intx_level(
    4.92 +            guest_handle_cast(arg, xen_hvm_set_pci_intx_level_t));
    4.93 +        break;
    4.94  
    4.95 -        d = find_domain_by_id(op.domid);
    4.96 -        if (d == NULL)
    4.97 -            return -ESRCH;
    4.98 +    case HVMOP_set_isa_irq_level:
    4.99 +        rc = hvmop_set_isa_irq_level(
   4.100 +            guest_handle_cast(arg, xen_hvm_set_isa_irq_level_t));
   4.101 +        break;
   4.102  
   4.103 -        rc = -EINVAL;
   4.104 -        if (is_hvm_domain(d)) {
   4.105 -            viosapic_set_irq(d, op.irq, op.level);
   4.106 -            rc = 0;
   4.107 -        }
   4.108 -
   4.109 -        put_domain(d);
   4.110 +    case HVMOP_set_pci_link_route:
   4.111 +        rc = 0;
   4.112          break;
   4.113 -    }
   4.114  
   4.115      default:
   4.116          gdprintk(XENLOG_INFO, "Bad HVM op %ld.\n", op);
     5.1 --- a/xen/include/asm-ia64/viosapic.h	Fri Dec 01 11:12:00 2006 -0700
     5.2 +++ b/xen/include/asm-ia64/viosapic.h	Fri Dec 01 11:40:57 2006 -0700
     5.3 @@ -42,7 +42,7 @@
     5.4  
     5.5  #define VIOSAPIC_VERSION_ID   0x21 /* IOSAPIC version */
     5.6  
     5.7 -#define VIOSAPIC_NUM_PINS     24
     5.8 +#define VIOSAPIC_NUM_PINS     48
     5.9  
    5.10  #define VIOSAPIC_DEFAULT_BASE_ADDRESS  0xfec00000
    5.11  #define VIOSAPIC_MEM_LENGTH            0x100
    5.12 @@ -74,19 +74,17 @@ union viosapic_rte
    5.13  };
    5.14  
    5.15  struct viosapic {
    5.16 -    uint32_t irr;
    5.17 -    uint32_t irr_xen; /* interrupts forced on by the hypervisor. */
    5.18 -    uint32_t isr;     /* This is used for level trigger */
    5.19 -    uint32_t imr;
    5.20 +    uint64_t irr;
    5.21 +    uint64_t isr;     /* This is used for level trigger */
    5.22      uint32_t ioregsel;
    5.23      spinlock_t lock;
    5.24 -    unsigned long base_address;
    5.25 +    uint64_t base_address;
    5.26      union viosapic_rte redirtbl[VIOSAPIC_NUM_PINS];
    5.27  };
    5.28  
    5.29  void viosapic_init(struct domain *d);
    5.30 -void viosapic_set_xen_irq(struct domain *d, int irq, int level);
    5.31  void viosapic_set_irq(struct domain *d, int irq, int level);
    5.32 +void viosapic_set_pci_irq(struct domain *d, int device, int intx, int level);
    5.33  void viosapic_write(struct vcpu *v, unsigned long addr,
    5.34                      unsigned long length, unsigned long val);
    5.35