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_SMPbad_irq_desc.affinity = CPU_MASK_ALL;bad_irq_desc.cpu = smp_processor_id();#endifxen_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);elseset_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=0for (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 > 32for (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.Sextern 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 0flush_icache_range(vectors, vectors + PAGE_SIZE);modify_domain(DOMAIN_USER, DOMAIN_CLIENT);#endif /* 0 */
}
static evtchn_desc_t evtchn_desc[NR_IRQS];//512void __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;
评论
发表评论