//   时钟mult :mult/2^shift = ns/cyc //    参考:http://www.bluezd.info/archives/reg_clock_event_device_1
//  x86平台初始化
//      注:arch/x86/kernel/x86_init.c
1.1 struct x86_init_ops x86_init __initdata = {...//时钟初始化.timers = {.setup_percpu_clockev = setup_boot_APIC_clock,.tsc_pre_init      = x86_init_noop,.timer_init        = hpet_time_init,},...
};//    时钟初始化
//  函数任务:
//      1.初始化hpet时钟源,时钟事件设备
//      2.初始化tsc时钟源
//  调用路径start_kernel->time_init
1.1 void __init time_init(void)
{//初始化hpet时钟源x86_init.timers.timer_init();tsc_init();
}// 初始化hpet
//  函数任务:
//      1.注册hpet clocksource,hpet clockevent
//      2.注册时钟中断处理程序
//  调用路径:time_init->hpet_time_init
2.1 void __init hpet_time_init(void)
{//注册hpet clocksource,hpet clockeventif (!hpet_enable())setup_pit_timer();//分配时钟中断setup_default_timer_irq();
}// 注册hpet时钟源
//  调用路径:hpet_time_init->hpet_enable->hpet_clocksource_register
//  函数任务:
//      1.初始化hpet clocksource硬件设备
//      2.检查hpet计数器是否正常工作
//          2.1 等待200000 tsc,判断hpet计数是否变化
//      3.计算hpet mult值
//      4.向系统注册hpet时钟源
2.2 static int hpet_clocksource_register(void)
{u64 start, now;cycle_t t1;//初始化hpet clocksource硬件设备hpet_restart_counter();//检测hpet计数器是否工作t1 = hpet_readl(HPET_COUNTER);rdtscll(start);//检测办法//    200000tsc之后,判断hpet计数器是否发生变化do {rep_nop();rdtscll(now);} while ((now - start) < 200000UL);if (t1 == hpet_readl(HPET_COUNTER)) {printk(KERN_WARNING"HPET counter not counting. HPET disabled\n");return -ENODEV;}//计算hpet clocksource的shift值clocksource_hpet.mult = div_sc(hpet_period, FSEC_PER_NSEC, HPET_SHIFT);//注册hpet时钟源clocksource_register(&clocksource_hpet);return 0;
}// hpet时钟源
2.3 static struct clocksource clocksource_hpet = {.name        = "hpet",.rating     = 250,//精度排名.read      = read_hpet,.mask      = HPET_MASK,.shift     = HPET_SHIFT,.flags        = CLOCK_SOURCE_IS_CONTINUOUS,//连续时钟源.resume        = hpet_resume_counter,};// 注册hpet 时钟事件设备
//  调用路径:hpet_time_init->hpet_enable->hpet_legacy_clockevent_register
//  函数任务:
//      1.hpet clockevent硬件初始化
//      2.计算hpet mult
//      3.计算hpet cpu掩码
//          3.1 IO_APIC初始化完成后,设置hpet对所有cpu可用
//      4.计算hpet clockevent设备可重新编程的最大、最小时间间隔
//      5.设置hpet clockevent设备为全局事件设备
//  注:
//      hpet clockevent存在可重新编程的上下时间间隔
3.1 static void hpet_legacy_clockevent_register(void)
{//hpet clockevent硬件初始化hpet_enable_legacy_int();//计算hpet clockevent的multhpet_clockevent.mult = div_sc((unsigned long) FSEC_PER_NSEC,hpet_period, hpet_clockevent.shift);//最大时间间隔hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF,&hpet_clockevent);//重新编程的最小时间间隔5ushpet_clockevent.min_delta_ns = 5000;//当io-apic初始化完成后,才会使hpet 服务于所有cpuhpet_clockevent.cpumask = cpumask_of(smp_processor_id());//注册hpet clockeventclockevents_register_device(&hpet_clockevent);//hpet作为全局时钟事件设备global_clock_event = &hpet_clockevent;
}// hpet clockevent设备
3.2 static struct clock_event_device hpet_clockevent = {.name      = "hpet",.features   = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,//支持周期和单触发模式.set_mode   = hpet_legacy_set_mode,.set_next_event = hpet_legacy_next_event,//设置事件将要发生的时间.shift       = 32,.irq      = 0,//使用0号irq.rating       = 50,
};//    时钟中断控制块
4.1 static struct irqaction irq0  = {.handler = timer_interrupt,.flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER,.name = "timer"
};//    设置时钟中断处理程序
//  调用路径:hpet_time_init->setup_default_timer_irq
4.2 void __init setup_default_timer_irq(void)
{setup_irq(0, &irq0);
}// 时钟中断处理程序
//  函数任务:
//      1.向中断控制器应答
//      2.通知全局时钟事件设备处理时间到期
4.3 static irqreturn_t timer_interrupt(int irq, void *dev_id)
{//向中断控制器应答时钟中断if (timer_ack) {raw_spin_lock(&i8259A_lock);outb(0x0c, PIC_MASTER_OCW3);/* Ack the IRQ; AEOI will end it automatically. */inb(PIC_MASTER_POLL);raw_spin_unlock(&i8259A_lock);}//全局时钟源设备的时间处理函数global_clock_event->event_handler(global_clock_event);if (MCA_bus)outb_p(inb_p(0x61)| 0x80, 0x61);return IRQ_HANDLED;
}

时间子系统10_hpet时钟初始化相关推荐

  1. Linux时间子系统之时钟源层(Clock Source)

    所谓时钟源设备,Linux将其抽象为一个可以记录时间流逝的设备,其值随着时间的流逝递增.将前一次读取的值和当前的值做比较就知道过去了多长的时间.但是它不一定是记录当前具体时间的设备,它只记录过去了多少 ...

  2. Linux时间子系统之八:动态时钟框架(CONFIG_NO_HZ、tickless)【转】

    转自:http://blog.csdn.net/droidphone/article/details/8112948 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] 数据结构 ...

  3. linux 多核 系统时钟,Linux时间子系统之(十五):clocksource

    Linux时间子系统之(十五):clocksource 作者:linuxer 发布于:2014-12-1 19:03 分类:时间子系统 一.前言 和洋葱一样,软件也是有层次的,内核往往需要对形形色色的 ...

  4. Linux时间子系统之三:时间的维护者:timekeeper

    专题文档汇总目录 Notes: 原文地址:Linux时间子系统之三:时间的维护者:timekeeper 本系列文章的前两节讨论了用于计时的时钟源:clocksource,以及内核内部时间的一些表示方法 ...

  5. Linux时间子系统(二) 软件架构

    一.前言 本文的主要内容是描述内核时间子系统的软件框架.首先介绍了从旧的时间子系统迁移到新的时间子系统的源由,介绍新的时间子系统的优势.第三章汇整了时间子系统的相关文件以及内核配置.最后描述各种内核配 ...

  6. Linux时间子系统之六:高精度定时器(HRTIMER)的原理和实现

    转自:http://blog.csdn.net/droidphone/article/details/8074892 上一篇文章,我介绍了传统的低分辨率定时器的实现原理.而随着内核的不断演进,大牛们已 ...

  7. Linux时间子系统之(五):POSIX Clock

    专题文档汇总目录 Notes: 本章主要介绍了若干种类的静态时钟,这些时钟都可以通过k_clock表示,注册到posix_clocks中.这些都是静态时钟,可以分为三大类:各种REALTIME时钟.带 ...

  8. Linux时间子系统之Tick层

    所谓Tick设备,也称作滴答设备,就是系统中的一个周期中断设备,其周期间隔由内核编译选项定义. Tick设备在Linux时间子系统中用tick_device结构体表示(代码位于kernel/time/ ...

  9. 解BUG-xenomai内核与linux内核时间子系统之间存在漂移

    版权声明:本文为本文为博主原创文章,转载请注明出处https://blog.csdn.net/qq_22654551.如有问题,欢迎指正. 一.问题起源 何为漂移?举个例子两颗32.768kHz晶振C ...

最新文章

  1. VMware HA实战攻略之五VMwareHA测试验收
  2. java 正则表达式语法_Java 正则表达式基础语法
  3. android入门学习-天气预报app(一)
  4. 模仿网易(163)首页Ajax功能中的鼠标延时触发
  5. axure菜单移动隐藏_如何使用隐藏的移动网络更快地完成工作
  6. SQL Server查询执行计划–基础
  7. PostFix邮件网关无法向公网投递邮件问题分析
  8. python安装详细步骤windows10_Windows10系统安装Python教程
  9. 改写自SqlHelper的SqliteHelper
  10. 太牛了!阿里p8全面透彻剖析《Netty权威指南》,程序员必看!
  11. linux串口编程(termios结构体说明)
  12. 20多年来,我国网络文学行业发生了天翻地覆的变化
  13. Word不计算封面、目录页数将正文页码修改为第几页共几页的格式
  14. 波士顿房价预测python决策树_波士顿房价预测 - 最简单入门机器学习 - Jupyter
  15. PS软件学习知识盘点
  16. G.652光纤各个子类的主要区别及应用
  17. 【个人C++学习日记】
  18. Java实现split字符串分割方法
  19. 【逗老师带你学IT】PRTG获取HUAWEI FusionServer iBMC传感器状态
  20. 实训|第十天从底层解释一下U盘内存为什么变小的原因附数据恢复的基本原理...

热门文章

  1. 申请著作权的流程有哪些
  2. python安装math模块_python math模块
  3. 网上书城项目的需求分析、数据库表设计及前端界面的编写(项目进度一)
  4. 数据结构(C语言版)之栈及递归
  5. GitHub下载 无法分配请求的地址_Hexo+Github--搭建个人博客(一)准备工作amp;amp;环境搭建
  6. java ee字体_[分享] 23种漂亮的字体代码,
  7. 腾讯数据科学家详解用户选择行为分析核心模型
  8. mysql如何进行数据透视_使用MySQL的数据透视表
  9. PostgreSQL之如何敲开PG的大门?
  10. 使用Rust开发编译系统(C以及Rust编译的过程)