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;

 

 

 

 

评论

此博客中的热门博文

Linux/ARM Page Table Entry 属性设置分析

提交了30次才AC ---【附】POJ 2488解题报告

笔记