Embeddedxen中断初始化

原创文章,转载请注明出处.转载自: Li Haifeng's Blog
本文链接地址: Embeddedxen中断初始化


xen中的中断初始化–和Linux的差不太多



typedef struct irqdesc {
 char   *type;


 irq_handler_t  handle;


 struct irqchip  *chip;


 struct irqaction  *action;


 unsigned int  flags;


 unsigned int  status;


 spinlock_t  lock;


 void   *chipdata;


 void   *data;


 unsigned int  disable_depth;


 /* Is this one of HID interrupts? */


 unsigned int  isHIDirq;


}irqdesc_t __cacheline_aligned; 


xen/arch/arm/hypervisor/irq.c


 




struct irqdesc irq_desc[NR_IRQS]; //128


 


 




void __init xen_init_IRQ(void)


{


 int irq;


 for (irq = 0; irq < NR_IRQS; irq++)
  irq_desc[irq].status |= IRQ_NO_REQUEST | IRQ_NO_PROBE;



#ifdef CONFIG_SMP
 bad_irq_desc.affinity = CPU_MASK_ALL;


 bad_irq_desc.cpu = smp_processor_id();


#endif



 xen_init_arch_irq();


}


xen/arch/arm/mach-pxa/mainstone.c


 


void __init xen_init_arch_irq(void)


{


 int irq;


 printk(“Initing arch-IRQ…n”);
 pxa_init_irq();


 /* setup extra Mainstone irqs */


 for(irq = MAINSTONE_IRQ(0); irq <= MAINSTONE_IRQ(15); irq++) {/*160–175*/



  set_irq_chip(irq, &mainstone_irq_chip);
  set_irq_handler(irq, level_irq_handler);


  if (irq == MAINSTONE_IRQ(10) || irq == MAINSTONE_IRQ(14))


   set_irq_flags(irq, IRQF_VALID | IRQF_TRIGGER_PROBE ); //| IRQF_TRIGGER_NO_AUTO_ENABLE);


  else


   set_irq_flags(irq, IRQF_VALID | IRQF_TRIGGER_PROBE);


 }


 set_irq_flags(MAINSTONE_IRQ(8), 0);


 set_irq_flags(MAINSTONE_IRQ(12), 0);



 MST_INTMSKENA = 0;
 MST_INTSETCLR = 0;



 set_irq_chained_handler(IRQ_GPIO(0), mainstone_irq_handler);
 set_irq_type(IRQ_GPIO(0), IRQT_RISING);



}


 xen/arch/arm/mach-pxa/irq.c




void __init pxa_init_irq(void)


{


 int irq;


 /* disable all IRQs */

 ICMR = 0;


 /* all IRQs are IRQ, not FIQ */

 ICLR = 0;


 /* clear all GPIO edge detects */

 GFER0 = 0;


 GFER1 = 0;


 GFER2 = 0;


 GRER0 = 0;


 GRER1 = 0;


 GRER2 = 0;


 GEDR0 = GEDR0;


 GEDR1 = GEDR1;


 GEDR2 = GEDR2;


#ifdef CONFIG_PXA27x

 /* And similarly for the extra regs on the PXA27x */


 ICMR2 = 0;


 ICLR2 = 0;


 GFER3 = 0;


 GRER3 = 0;


 GEDR3 = GEDR3;


#endif


 /* only unmasked interrupts kick us out of idle */

 ICCR = 1;


 /* GPIO 0 and 1 must have their mask bit always set */

 GPIO_IRQ_mask[0] = 3;


 //NR_IRQS=512

 //PXA_IRQ_SKIP=0


 for (irq = PXA_IRQ(PXA_IRQ_SKIP); irq <= PXA_IRQ(31); irq++) {


  set_irq_chip(irq, &pxa_internal_chip_low);


  set_irq_handler(irq, level_irq_handler);


  set_irq_flags(irq, IRQF_VALID);


 }


#if PXA_INTERNAL_IRQS > 32

 for (irq = PXA_IRQ(32); irq < PXA_IRQ(PXA_INTERNAL_IRQS); irq++) {


  set_irq_chip(irq, &pxa_internal_chip_high);


  set_irq_handler(irq, level_irq_handler);


  set_irq_flags(irq, IRQF_VALID);


 }


#endif


 for (irq = IRQ_GPIO0; irq <= IRQ_GPIO1; irq++) {

  set_irq_chip(irq, &pxa_low_gpio_chip);


  set_irq_handler(irq, edge_irq_handler);


  set_irq_flags(irq, IRQF_VALID | IRQF_TRIGGER_PROBE);


 }


 for (irq = IRQ_GPIO(2); irq <= IRQ_GPIO(PXA_LAST_GPIO); irq++) {

  set_irq_chip(irq, &pxa_muxed_gpio_chip);


  set_irq_handler(irq, edge_irq_handler);


  set_irq_flags(irq, IRQF_VALID | IRQF_TRIGGER_PROBE);


 }


 /* Install handler for GPIO>=2 edge detect interrupts */

 set_irq_chip(IRQ_GPIO_2_x, &pxa_internal_chip_low);


 set_irq_chained_handler(IRQ_GPIO_2_x, pxa_gpio_demux_handler);


}


 以上是xen中的中断初始化分析。下面看一下DOM的中断初始化。在DOM中,实际上没有了中断的概念,全部被evtchn_desc_t所替代了


 


DOM


 


arch/arm/kernel/traps-xen.c



void __init trap_init(void)
{


 //unsigned long vectors = CONFIG_VECTORS_BASE;

 unsigned long vectors = (unsigned long) __guestvectors;//.extern __guestvectors  arch/arm/kernel/entry-armv-xen.S


 extern char __stubs_start[], __stubs_end[];


 extern char __vectors_start[], __vectors_end[];


 extern char __kuser_helper_start[], __kuser_helper_end[];


 int kuser_sz = __kuser_helper_end – __kuser_helper_start;


 /*

  * Copy the vectors, stubs and kuser helpers (in entry-armv.S)


  * into the vector page, mapped at 0xffff0000, and ensure these


  * are visible to the instruction stream.


  */


 memcpy((void *)vectors, __vectors_start, __vectors_end – __vectors_start);


 memcpy((void *)vectors + 0x200, __stubs_start, __stubs_end – __stubs_start);


 memcpy((void *)vectors + 0x1000 – kuser_sz, __kuser_helper_start, kuser_sz);


 /*

  * Copy signal return handlers into the vector page, and


  * set sigreturn to be a pointer to these.


  */


 memcpy((void *)KERN_SIGRETURN_CODE, sigreturn_codes,


        sizeof(sigreturn_codes));


/* (GCD) From Samsung */

#if 0


 flush_icache_range(vectors, vectors + PAGE_SIZE);


 modify_domain(DOMAIN_USER, DOMAIN_CLIENT);


#endif /* 0 */


}




static evtchn_desc_t evtchn_desc[NR_IRQS];//512


 


 


void __init init_IRQ(void)


{


 int i;


 int cpu;


 spin_lock_init(&irq_mapping_update_lock);

 init_evtchn_cpu_bindings();

 /* No VIRQ or IPI bindings. */

 for (cpu = 0; cpu < NR_CPUS; cpu++) {


  for (i = 0; i < NR_VIRQS; i++)


   per_cpu(virq_to_irq, cpu)[i] = -1;


  for (i = 0; i < NR_IPIS; i++)


   per_cpu(ipi_to_irq, cpu)[i] = -1;


 }


 /* No event-channel -> IRQ mappings. */

 for (i = 0; i < NR_EVENT_CHANNELS; i++) {


  evtchn_to_irq[i] = -1;


  mask_evtchn(i); /* No event channels are ‘live’ right now. */


 }


 /* No IRQ -> event-channel mappings. */

 for (i = 0; i < NR_IRQS; i++)


  irq_info[i] = IRQ_UNBOUND;


 /* Dynamic IRQ space is currently unbound. Zero the refcnts. */

 for (i = 0; i < NR_DYNIRQS; i++) {


  irq_bindcount[dynirq_to_irq(i)] = 0;


  evtchn_desc[dynirq_to_irq(i)].status  = IRQ_DISABLED;

  evtchn_desc[dynirq_to_irq(i)].action  = NULL;


  evtchn_desc[dynirq_to_irq(i)].depth   = 1;


  evtchn_desc[dynirq_to_irq(i)].handler = &dynirq_type;


  evtchn_desc[dynirq_to_irq(i)].lock = __SPIN_LOCK_UNLOCKED(evtchn_desc->lock);


 }


 /* Phys IRQ space is statically bound (1:1 mapping). Nail refcnts. */

 for (i = 0; i < NR_PIRQS; i++) {


  irq_bindcount[pirq_to_irq(i)] = 1;


  evtchn_desc[pirq_to_irq(i)].status  = IRQ_DISABLED;

  evtchn_desc[pirq_to_irq(i)].action  = NULL;


  evtchn_desc[pirq_to_irq(i)].depth   = 1;


  evtchn_desc[pirq_to_irq(i)].handler = &pirq_type;


  evtchn_desc[pirq_to_irq(i)].lock = __SPIN_LOCK_UNLOCKED(evtchn_desc->lock);


 }


}


 




typedef struct hw_interrupt_type hw_irq_controller;


 


struct hw_interrupt_type {
 const char *typename;


 unsigned int (*startup)(unsigned int irq);


 void (*shutdown)(unsigned int irq);


 void (*enable)(unsigned int irq);


 void (*disable)(unsigned int irq);


 void (*ack)(unsigned int irq);


 void (*end)(unsigned int irq);


 void (*set_affinity)(unsigned int irq, cpumask_t dest);


 int (*set_type)(unsigned int irq, unsigned int type);


 void (*release)(unsigned int irq, void *dev_id);


};


 



typedef struct evtchn_desc {

 hw_irq_controller *handler;


 void *handler_data;


 struct irqaction *action; /* IRQ action list */


 unsigned int status; /* IRQ status */


 unsigned int depth; /* nested irq disables */


 unsigned int irq_count; /* For detecting broken interrupts */


 unsigned int irqs_unhandled;


 spinlock_t lock;


#if defined (CONFIG_GENERIC_PENDING_IRQ) || defined (CONFIG_IRQBALANCE)


unsigned int move_irq; /* Flag need to re-target intr dest*/


#endif


} evtchn_desc_t;


 


 


 


 


From Li Haifeng's Blog, post Embeddedxen中断初始化

Post Footer automatically generated by wp-posturl plugin for wordpress.

分享到: