博文

目前显示的是标签为“EmbeddedXEN”的博文

EmbeddedXENVIRQ发送流程

图片
Hypervisor发送virq的函数有两个: 一个是send_geust_vcpu_virq,另一个是send_guest_global_virq void send_guest_vcpu_virq(struct vcpu *v, int virq) {     int port;     ASSERT(!virq_is_global(virq));     port = v->virq_to_evtchn[virq];     if ( unlikely(port == 0) ) {         return;     }      evtchn_set_pending (v, port); } void send_guest_global_virq(struct domain *d, int virq) {     int port;     struct vcpu *v;     struct evtchn *chn;     ASSERT(virq_is_global(virq));     if ( unlikely(d == NULL) )         return;     v = d->vcpu[0];     if ( unlikely(v == NULL) )         return;     port = v->virq_to_evtchn[virq];     if ( unlikely(port == 0) )         return;     chn = evtchn_from_port(d, port);      evtchn_set_pending (d->vcpu[chn->notify_vcpu_id], port); } send_guest_vcpu_virq的调用关系是这样的: 图中的两个定时器是在分配vcpu的时候安装的。 send_guest_global_virq的调用关系比较复杂,都是发给DOM0的

EmbeddedXEN VIRQ申请

为了说明VIRQ,拿时间中断的注册为例来说明Virq的申请过程,明白了VIRQ申请过程后,我们简单的看一下DOMU console的注册过程。 arch/arm/mach-pxa/time-xen.c MACHINE_START( MAINSTONE , "Intel HCDDBBVA0 Development Platform (aka Mainstone) / EmbeddedXEN (xen-pxa270-qemu)") /* Maintainer: MontaVista Software Inc. */ .phys_io = 0x40000000, .boot_params = 0xa0000100, /* BLOB boot parameter setting */ .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .timer = & pxa_timer , .init_machine = mainstone_init MACHINE_END struct sys_timer pxa_timer  = { .init =  pxa_timer_init , /* .suspend = pxa_timer_suspend, .resume = pxa_timer_resume, */ .offset = pxa_gettimeoffset, }; -----------------好了,上面是数据结构,以及定义,现在看一下怎么用这些数据的----- init/main-xen.c asmlinkage void  __init start_kernel_lx0(void) {     ......      time_init();  /* (DRE) xen guest */     ...... } arch/arm/kernel/time.c void __init time_init(void) { if (system_timer->offset == NULL) system_timer->offset = dummy_gettimeoffset; system_timer->init() ; #ifdef CONFIG_NO...

超级调用swi 82的最初流程

xen/arch/arm/kernel/entry-armv.S __vectors_start: swi SYS_ERROR0 /* Reset */ b vector_undefined_instruction + stubs_offset ldr pc,   .LCvswi   + stubs_offset b vector_prefetch_abort + stubs_offset b vector_data_abort + stubs_offset b vector_addrexcptn + stubs_offset b vector_irq + stubs_offset b vector_fiq + stubs_offset .globl __vectors_end __vectors_end: /*  * We group all the following data together to optimise  * for CPUs with separate I & D caches.  */ .align 5 .LCvswi: .word   vector_swi -------------- xen/arch/arm/hypervisor/hypervisor.S ENTRY( vector_swi ) sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - r12} add r8, sp, #S_PC stmdb r8, {sp, lr}^ mrs r8, spsr str lr, [sp, #S_PC] str r8, [sp, #S_PSR] vcpu r8 add r8, r8, #(OFFSET_ARCH_VCPU + OFFSET_GUEST_CONTEXT) ldr r9, [r8, #(OFFSET_SYS_REGS+OFFSET_VPSR)] ldr r10, [sp, #S_SP] cmp r9, #PSR_MODE_USR streq   r10, [r8, #(OFFSET_SYS_REGS+OFFSET_VUSP)] strne   r10, [r8, #(OFFSET_SYS_REGS+OFFSET_VKSP)] ldr     r8, [sp, #S_PSR] bic     r8...

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, &mainston...

Embeddedxen中断申请

先看xen的中断申请 申请中断离不开request_irq和setup_irq xen只申请了两个irq一个是timer的,另一个是console. xen/arch/arm/mach-pxa/time.c void __init xen_pxa_timer_init(void) { unsigned long clock_tick_rate; OIER = 0; OSSR = OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3; if (cpu_is_pxa25x()) clock_tick_rate = 3686400; else if (machine_is_mainstone()) clock_tick_rate = 3249600; else clock_tick_rate = 3250000; set_oscr2ns_scale(clock_tick_rate); ckevt_pxa_osmr0.mult = div_sc(clock_tick_rate, NSEC_PER_SEC, ckevt_pxa_osmr0.shift); ckevt_pxa_osmr0.max_delta_ns = clockevent_delta2ns(0x7fffffff, &ckevt_pxa_osmr0); ckevt_pxa_osmr0.min_delta_ns = clockevent_delta2ns(MIN_OSCR_DELTA * 2, &ckevt_pxa_osmr0) + 1; cksrc_pxa_oscr0.mult = clocksource_hz2mult(clock_tick_rate, cksrc_pxa_oscr0.shift); setup_irq (IRQ_OST0, & pxa_ost0_irq ); /* timebase_freq = CLOCK_TICK_RATE: source clock rate in Hz */ //timebase_freq = 1000000LL; timebase_freq = CLOCK_TICK_RATE; system_timer_clocksource = &cksrc_pxa_oscr0; system_timer_clockevent ...

中断响应,从Embeddedxen到DOM

图片
最初的跳转: arch/arm/kernel/entry-armv.S __irq_svc: svc_entry #ifdef CONFIG_PREEMPT get_thread_info tsk ldr r8, [tsk, #TI_PREEMPT] @ get preempt count add r7, r8, #1 @ increment it str r7, [tsk, #TI_PREEMPT] #endif irq_handler ...  __irq_usr: usr_entry get_thread_info tsk #ifdef CONFIG_PREEMPT ldr r8, [tsk, #TI_PREEMPT] @ get preempt count add r7, r8, #1 @ increment it str r7, [tsk, #TI_PREEMPT] #endif irq_handler .macro irq_handler 1: get_irqnr_and_base r0, r6, r5, lr movne r1, sp @ @ routine called with r0 = irq number, r1 = struct pt_regs * @ adrne lr, 1b bne  asm_do_IRQ 看asm_do_IRQ: xen/arch/arm/hypervisor/irq.c asmlinkage void asm_do_IRQ(unsigned int irq, struct xen_cpu_user_regs *regs) { struct irqdesc *desc; if (irq >= NR_IRQS) { printk("Bad IRQ = %d\n", irq); }   /* (GCD) CONFIG_XEN_BENCHMARK    * GPIO37 irq#69 is decode from interrupt #10 in pxa_gpio_demux_handler() function    * See file xen/arch/arm/mach-pxa/irq.c    */ desc = get_irq_descriptor(irq); desc-> handl...

embeddedxen中xen的时间中断分析

需要注意的一点是,这里的timer_softirq和DOMU里面的并不一样。本文仅浅析xen里面的timer 执行顺序: irq来了以后->time_irq_handler->调用其他函数->raise_softirq(TIMER_SOFTIRQ)->timer_softirq_action->(定时器timer->fn())->raise_softirq(SCHEDULE_SOFTIRQ)->schedule() timer_init();------open_softirq(TIMER_SOFTIRQ,  timer_softirq_action ); | init_xen_time()//这个函数里面有很多故事 | init_platform_timer(); | xen_pxa_timer_init(); | setup_irq(IRQ_OST0, &pxa_ost0_irq);//IRQ_OST0 是26   也就是安装了IRQ,那么,看一下pxa_ost0_irq static struct irqaction pxa_ost0_irq = { .name = "ost0", .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, .handler = pxa_ost0_interrupt, .dev_id = &ckevt_pxa_osmr0, }; 看到它的handler是pxa_ost0_interrupt static irqreturn_t pxa_ost0_interrupt(int irq, void *dev_id, struct pt_regs *regs) { //struct clock_event_device *c = dev_id;     //static int cnt = 0;   /* Disarm the compare/match, signal the event. */ OIER &= ~OIER_E0; OSSR = OSSR_M0;   timer_interrupt(irq, dev_id, regs);   return IRQ_HANDLED; } 当发生时间中断...