时间子系统1_lapic时钟初始化

来源:互联网 发布:ubuntu什么系统 编辑:程序博客网 时间:2024/06/08 09:57
//参考:http://www.bluezd.info/archives/reg_clock_event_device_1//x86平台初始化//注:arch/x86/kernel/x86_init.c1.1 struct x86_init_ops x86_init __initdata = {...//apic控制器初始化.irqs = {.pre_vector_init= init_ISA_irqs,.intr_init= native_init_IRQ,.trap_init= x86_init_noop,},...};//中断初始化//调用路径:start_kernel->init_IRQ1.2void __init init_IRQ(void){//中断初始化...x86_init.irqs.intr_init();}//x86体系结构中断初始化//函数任务://1.初始化isa 0~15号中断//2.初始化apic中断1.3 void __init native_init_IRQ(void){int i;//初始化isa 0~15号中断x86_init.irqs.pre_vector_init();//初始化apic中断apic_intr_init();...}//apic中断初始化//函数任务://1.smp 中断初始化//2.lapic时钟中断初始化//3.x86平台专用ipi//4.其他1.4 static void __init apic_intr_init(void){//smp 中断初始化smp_intr_init();...#if defined(CONFIG_X86_64) || defined(CONFIG_X86_LOCAL_APIC)//lapic时钟中断初始化alloc_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt);//x86平台专用ipialloc_intr_gate(X86_PLATFORM_IPI_VECTOR, x86_platform_ipi);...#endif}//smp ipi中断初始化//函数任务://1.cpu间重调度ipi//2.cpu间函数调用ipi//3.系统关机,重启ipi//4.其他1.5 static void __init smp_intr_init(void){#ifdef CONFIG_SMP#if defined(CONFIG_X86_64) || defined(CONFIG_X86_LOCAL_APIC)//cpu间重调度ipi,由wake_up驱动alloc_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt);//cpu间函数调用ipi,通知其他cpu在中断上下文执行某函数alloc_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt);alloc_intr_gate(CALL_FUNCTION_SINGLE_VECTOR,call_function_single_interrupt);//系统关机,重启ipialloc_intr_gate(REBOOT_VECTOR, reboot_interrupt);#endif#endif }//lapic时钟中断//注:#define LOCAL_TIMER_VECTOR0xef1.6 void __irq_entry smp_apic_timer_interrupt(struct pt_regs *regs){struct pt_regs *old_regs = set_irq_regs(regs);//ack irqack_APIC_irq();//如果本cpu上运行idle进程,退出idle状态exit_idle();irq_enter();//lapic的时钟处理函数local_apic_timer_interrupt();irq_exit();set_irq_regs(old_regs);}//lapic时钟中断处理程序//函数任务://1.检查是否为错误的中断信号//1.1 lapic中断比lapic时钟源先使能,因此产生中断时,//可能相应的事件处理函数还没有建立,此时,关闭时钟源,退出处理//2.统计apic中断次数//3.执行apic事件处理函数1.7 static void local_apic_timer_interrupt(void){int cpu = smp_processor_id();//lapic per-cpu clockevent 设备struct clock_event_device *evt = &per_cpu(lapic_events, cpu);//lapic中断比lapic时钟源先使能,因此产生中断时,可能相应的事件处理函数还没有建立if (!evt->event_handler) {//错误的中断信号,关闭时钟源pr_warning("Spurious LAPIC timer interrupt on cpu %d\n", cpu);lapic_timer_setup(CLOCK_EVT_MODE_SHUTDOWN, evt);return;}//apic中断统计inc_irq_stat(apic_timer_irqs);//执行apic事件处理函数evt->event_handler(evt);}//创建lapic时钟源//函数任务://1.设置lapic服务当前cpu//2.注册lapic设备2.1 static void __cpuinit setup_APIC_timer(void){//本cpu的lapicstruct clock_event_device *levt = &__get_cpu_var(lapic_events);//lapic受省电模式C3的影响if (cpu_has(¤t_cpu_data, X86_FEATURE_ARAT)) {lapic_clockevent.features &= ~CLOCK_EVT_FEAT_C3STOP;lapic_clockevent.rating = 150;}//lapic_clockevent作为所有lapic clockevent模板memcpy(levt, &lapic_clockevent, sizeof(*levt));//lapic服务的cpulevt->cpumask = cpumask_of(smp_processor_id());//注册lapic设备clockevents_register_device(levt);}//lapic clockevent设备//注:lapic在注册时,默认关闭状态2.1 static struct clock_event_device lapic_clockevent = {.name= "lapic",.features= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT| CLOCK_EVT_FEAT_C3STOP | CLOCK_EVT_FEAT_DUMMY,.shift= 32,.set_mode= lapic_timer_setup,.set_next_event= lapic_next_event,.broadcast= lapic_timer_broadcast,.rating= 100,.irq= -1,};

原创粉丝点击