Linux 驱动开发 三十四:Linux 内核定时器原理

参考文档:
《Cortex -A7 MPCore Technical Reference Manual》Chapter 9:Generic Timer
《ARM ® Architecture Reference Manual ARMv7-A and ARMv7-R edition》Chapter B8:The Generic Timer

一、Chapter B8 The Generic Timer 翻译

这一章节描述 ARM 通用定时器的实现ARM 通用定时器实现对于 ARMv7-AARMv7-R 架构处理器是一个可扩展选项。它包括定义了 ARM 通用寄存器的系统控制接口。

包含以下章节:

  • 关于通用定时器B8-1960 页)
  • 通用定时器寄存器摘要B8-1969 页)

Appendix D5 System Level Implementation of the Generic Timer 描述通用定时器系统实现等级

注:Chapter B4 System Control Registers in a VMSA implementationChapter B6 System Control Registers in a PMSA implementation 都描述通用定时器 CP15 寄存器大多数寄存器被包含在 VMSAPMSA 实现中,对于这些寄存器,VMSAPMSA 实现中的位分配是相同的。但是,本章中的大多数寄存器引用都链接到 Chapter B4 中的寄存器描述。

1、关于通用定时器

B8-1 中展示使用通用定时器作为系统定时器的一个片上系统的示例。在这个图片中:

  • 本手册定义了多处理器块中各个处理器的体系结构。

  • 《ARM Generic Interrupt Controller Architecture Specification》GIC 定义了一个可能的架构。

  • 通用计时器功能分布在多个组件中。
    在这里插入图片描述
    本章:

  • 给出通用定时器一般描述

  • 定义通用计时器的系统控制寄存器接口。图 B8-1 中所示的每个处理器都包含此接口的实现。

通用定时器:

  • 提供一个系统计数器,实时测量时间的流逝。
  • 支持虚拟化的系统中,支持测量虚拟时间流逝的虚拟计数器。也就是说,虚拟计数器可以测量特定虚拟机上的时间流逝。
  • 提供定时器,它可以在一段时间过去后断言计时器输出信号。计时器:
    • 可以向上向下计数。
    • 在支持虚拟化的组件中,可以实时或虚拟运行。

注:定时器输出信号可以用作电平敏感中断信号。

1、系统计数器

通用定时器提供了一个具有以下规范的系统计数器:

Width:至少 56 位宽。计数器的任何 64 位读取返回的值都是零扩展为 64 位。

Frequency固定频率的增量,通常在 1-50MHz 范围内。可以支持一种或多种可选的工作模式,在这种模式下,它以较低的频率递增较大的数量,通常用于节省功耗。

Roll-over:周转时间不少于 40 年。

AccuracyARM 没有指定所需的精度,但建议计数器在 24 小时周期内增益或损失不超过 10 秒。低频模式的使用不能影响实现的精度。

Start-up:从零开始运行。

系统计数器必须提供系统时间的统一视图。更准确地说,以下事件序列必须无法显示系统时间的倒退:

  • 设备 A 从系统计数器读取时间。
  • 设备 A 与系统中的另一个设备 B 通信。
  • 设备 B 识别出与设备 A 的通信后,从系统计数器中读取时间。

系统计数器必须在始终接通的电源域中实现。

为了支持低功耗工作模式,计数器可以在较低频率下以更大的数量递增。例如,一个 10MHz 的系统计数器可以增加:

  • 10MHz 增加 1
  • 20kHz 增加 500,当系统降低时钟频率时,降低功耗

在这种情况下,计数器必须支持高频率高精度低频率低精度之间的转换,而不影响计数器所需的精度

软件可以访问 CNTFRQ 寄存器以读取系统计数器的时钟频率,并且具有足够权限的软件可以修改该寄存器的值。详细信息见 Initializing and reading the system counter frequency

从系统计数器的计数被分配到系统组件的机制是由具体实现定义的,但是每个具有系统控制寄存器接口到系统计数器的处理器必须包含一个计数器输入,该输入可以捕获计数器的每个增量。

注:因此,系统计数器可以独立于处理器进行计时,计数值可以使用 Gray 代码序列进行分配。Gray-count scheme for timer distribution scheme on page D5-2427 给出更多信息。

初始化和读取系统计数器频率

通常,系统以固定频率驱动系统计数器,在系统引导过程中,CNTFRQ 寄存器必须编程为这个值。在一个支持 ARM 安全扩展的实现中,只有在安全 PL1 模式下执行的软件才能写入 CNTFRQ。如果系统允许对系统计数器频率进行任何配置,则必须确保 CNTFRQ 始终编程为正确的系统计数器频率。

注:CNTFRQ 寄存器在复位时是未知的,因此计数器频率必须写入 CNTFRQ 作为系统引导过程的一部分。

软件可以读取 CNTFRQ 寄存器,以确定当前系统计数器频率,处于以下状态和模式:

  • 不安全的 PL2 模式。
  • 安全和非安全 PL1 模式。
  • CNTKCTL.PL0PCTEN 设置为 1 时,“安全"和"不安全” PL0 模式。

系统计数器的内存映射控件

某些系统计数器控件只能通过与系统计数器的内存映射接口进行访问。这些控件包括:

  • 启用和禁用计数器。
  • 设置计数器值。
  • 更改操作模式,以更改更新频率和增量值。
  • 启用调试时暂停,然后调试器可以使用该调试器挂起计数。

对于更多描述见 Appendix D5 System Level Implementation of the Generic Timer

2、物理计数器

处理器提供一个物理计数器,该计数器包含系统计数器的计数值。CNTPCT 寄存器保存当前的物理计数器值。

访问物理计数器

具有足够权限的软件可以使用 64 位系统控制寄存器读取 CNTPCT

不包括虚拟化扩展的实现中,无论安全状态如何,始终可以从 PL1 模式访问 CNTPCT

包含虚拟化扩展的实现中,CNTPCT

  • 始终可以从安全 PL1 模式和非安全 Hyp 模式访问。
  • 仅当 CNTHCTL.PL1PCTEN 设置为 1 时,才能从非安全 PL1 模式访问。当 CNTHCTL.PL1PCTEN 设置为 0 时,任何从非安全 PL1 模式访问 CNTPCT 的尝试都会产生一个 Hyp Trap 异常。详细信息见 Hyp Trap exception on page B1-1209

此外,当 CNTHCTL.PL1PCTEN 设置为 1 时,如果在当前安全状态下可以从 PL1 模式访问 CNTPCT,那么在该安全状态下也可以从 PL0 模式访问 CNTPCT

CNTKCTL.PL0PCTEN 设置为 0 时,任何从 PL0 模式访问 CNTPCT 的尝试都会产生一个 Undefined Instruction 异常。

在包含虚拟化扩展的实现中:

  • CNTKCTL 控件的优先级高于 CNTHCTL 控件。当下面两个都适用时,这意味着尝试从非安全 PL0 模式访问 CNTPCT 会产生一个Undefined Instruction 异常:
    • CNTHCTL.PL1PCTEN 设置为 0 ,表示禁止非安全 PL1 模式访问。
    • CNTHCTL.PL0PCTEN 设置为 0,表示禁止 PL0 模式访问。
  • 启用 PL0 访问后,CNTHCTL 将应用于不安全的 PL0 访问。当同时满足以下两种情况时,这意味着尝试从非安全 PL0 模式访问 CNTPCT 将生成 Hyp Trap 异常:
    • CNTHCTL.PL1PCTEN 设置为 0,禁用非安全 PL1 模式访问。
    • CNTHCTL.PL0PCTEN 设置为 1 ,以允许从 PL0 模式访问。

CNTPCT 的读取可以推测性地发生,并且相对于在同一处理器上执行的其他指令而言是无序的。例如,如果从内存中读取用于从另一个代理获取信号,该信号指示必须读取 CNTPCT,必须使用 ISB 来确保在从存储器读取信号后读取 CNTPCT,如以下代码序列所示:
在这里插入图片描述

3、虚拟计数器

通用计时器的实现始终包括一个虚拟计数器,该计数器指示虚拟时间:

  • 不包括虚拟化扩展的处理器实现中,虚拟时间与物理时间相同,并且虚拟计数器包含与物理计数器相同的值。
  • 包含虚拟化扩展的处理器实现中,虚拟计数器包含物理计数器的值减去 64 位虚拟偏移量。在不安全的 PL1PL0 模式下执行时,虚拟偏移量值与当前虚拟机相关。

包含虚拟化扩展的处理器实现中,CNTVOFF 寄存器包含虚拟偏移。CNTVOFF 只能从 Hyp 模式访问,当 SCR.NS 设置为 1 时,只能从监视器模式访问。

注:通用计时器的所有实现都包括虚拟计数器。但是,只有支持虚拟化的系统才能明确区分物理时间和虚拟时间,并且:

  • 支持虚拟化的系统中,CNTVOFF 作为 RW 寄存器实现。
  • 不支持虚拟化的系统中:
    • 如果系统包含安全扩展,则从安全监视器模式访问 CNTVOFF 是不可预测的。
    • 虚拟计数器的行为就像 CNTVOFF 为零一样。

更多信息看 Status of the CNTVOFF register on page B8-1970

CNTVCT 寄存器保存当前虚拟计数器值。

访问虚拟计数器

具有足够权限的软件可以使用 64 位系统控制寄存器读取 CNTVCT

CNTVCT 始终可从安全 PL1 模式以及非安全 PL1PL2 模式访问。

此外,当 CNTKCTL.PL0VCTEN 设置为 1 时,可以从 PL0 模式访问 CNTVCT

CNTKCTL.PL0VCTEN 设置为 0 时,任何从 PL0 模式访问 CNTVCT 的尝试都会生成 Undefined Instruction 异常。

CNTVCT 的读取可以推测性地发生,并且相对于在同一处理器上执行的其他指令而言是无序的。例如,如果从内存中读取用于从另一个代理获取指示必须读取 CNTVCT 的信号,必须使用 ISB 来确保在从内存读取信号后读取 CNTVCT,如以下代码序列所示:
在这里插入图片描述

4、事件流

包含通用计时器的实现可以使用系统计数器生成一个或多个事件流,以生成定期唤醒事件,作为 Wait For Event and Send Event on page B1-1200 中描述的机制的一部分。

注:可以使用事件流:

  • 对等待事件轮询循环施加超时。
  • 防止任何导致不会生成预期事件的编程错误。

事件流通过以下方式配置:

  • 从计数器的底部 16 位中选择哪个位将生成事件。这决定了流中事件的频率。
  • 选择是在所选计数器位的每个 01 转换或每个 10 转换时生成事件。

CNTKCTL.{EVNTEN, EVNTDIR, EVNTI} 字段定义从虚拟计数器生成的事件流。

在包含虚拟化扩展的实现中,CNTHCTL.{EVNTEN, EVNTDIR, EVNTI} 字段定义从物理计数器生成的事件流。

事件流的操作如下:

  • 伪代码变量 PreviousCNTVCTPreviousCNTPCT 声明为:
// Variables used for generation of the timer event stream. 
bits(64) PreviousCNTVCT; 
bits(64) PreviousCNTPCT;
  • 伪代码函数 TestEventCNTV()TestEventCNTP() 在处理器时钟的每个周期上调用。
  • TestEventCNTx() 伪代码模板定义了函数 TestEventCNTV()TestEventCNTP()
    在这里插入图片描述

5、定时器

通用计时器的实现提供的计时器数取决于实现是否包括安全扩展和虚拟化扩展,如下所示:

未实现安全扩展插件

该实现提供了物理计时器和虚拟计时器。

已实现安全扩展,未实施虚拟化扩展

该实现提供:

  • 不安全的物理计时器。
  • 安全的物理计时器。
  • 虚拟计时器。

实现的虚拟化扩展

该实现提供:

  • 不安全的 PL1 物理计时器。
  • 安全 PL1 物理计时器。
  • 不安全的 PL2 物理计时器。
  • 虚拟计时器。

每个已实现计时器的输出:

  • 向系统提供输出信号。
  • 如果处理器连接到通用中断控制器 (GIC),则向该 GIC 发出专用外设中断 (PPI) 信号。在多处理器实现中,每个处理器必须为每个计时器使用相同的中断号。

每个计时器实现为三个寄存器:

  • 64CompareValue 寄存器,提供 64 位无符号 upcounter
  • 一个 32 位的 TimerValue 寄存器,它提供了一个 32 位的签名下行计数器。
  • 32 位控制寄存器。

在包含安全扩展的处理器实现中,PL1 物理计时器的寄存器被存放,以提供计时器的安全和非安全实现。表 B8-1 显示了定时器寄存器。
在这里插入图片描述
Table B8-2 on page B8-1969 包括对这些寄存器的描述的引用。

以下各节介绍计时器的操作:

  • 访问计时器寄存器
  • 定时器的 CompareValue 视图的操作
  • 定时器的 TimerValue 视图的操作
  • 操作时输出定时器信号

访问计时器寄存器

对于每个计时器,所有计时器寄存器都具有相同的访问权限,如下所示:

  • PL1 physical timer

    PL1 模式访问,除非实现包括虚拟化扩展,否则执行在 PL2 上的非安全软件控制从非安全 PL1 模式访问。

    当允许从 PL1 模式访问时,CNTKCTL.PL0PTEN 确定寄存器是否可以从 PL0 模式访问。如果因为 CNTKCTL.PL0PTEN 被设置为 0 而不允许访问,尝试从 PL0 模式访问会产生一个 Undefined Instruction 异常。

    如果实现包括安全扩展插件:

    • 除了从 Monitor 模式访问外,访问都是针对当前安全状态的寄存器。
    • 对于 Monitor 模式的访问,SCR.NS 的值决定访问的是安全寄存器还是非安全寄存器。

    如果实现包括虚拟化扩展:

    • 非安全寄存器可从 Hyp 模式访问。

    • CNTHCTL.PL1PCEN 确定非安全寄存器是否可以从非安全 PL1 模式访问。如果此位设置为 1,则启用从非安全 PL1 模式的访问,CNTKCTL.PL0PTEN 将确定寄存器是否可以从非安全 PL0 模式访问。

      如果因为 CNTHCTL.PL1PCEN 设置为 0 而不允许访问,则从非安全PL1或PL0模式访问时,会产生 Hyp Trap 异常。但是,如果 CNTKCTL.PL0PTEN 设置为 0 ,这个控件优先,并且试图从 PL0 访问会产生一个 Undefined Instruction 异常。

  • Virtual timer

    可从安全和非安全 PL1 模式以及 Hyp 模式访问。

    CNTKCTL.PL0VTEN 确定寄存器是否可以从 PL0 模式访问。如果因为 CNTKCTL.PL0VTEN 被设置为 0 而不允许访问,尝试从 PL0 模式访问会产生一个 Undefined Instruction 异常。

  • PL2 physical timer

    SCR.NS 设置为 1 时,可从非安全催眠模式以及从安全监视器模式访问。

定时器的 CompareValue 视图的操作

计时器的 CompareValue 视图作为 64upcounter 运行。当相应的计数器达到编程到 CompareValue 寄存器中的值时,满足定时器条件。当计时器条件满足时,只有当计时器启用,且该信号在相应的计时器控制寄存器 CNTP_CTLCNTHP_CTLCNTV_CTL 中没有被屏蔽时,才会断言定时器输出信号。

注:

  • 定时器输出信号可用作电平敏感中断信号。
  • CompareValue 视图操作的伪代码描述中,EventTriggered 指示是否满足计时器条件。它不指示是否断言定时器输出信号。

计时器的此视图的操作是:

EventTriggered = (((Counter[63:0] – Offset[63:0])[63:0] - CompareValue[63:0]) >= 0)

EventTriggered:如果满足此计时器的条件,则为 TRUE,否则为 FALSE

Counter:物理计数器值,可以从 CNTPCT 寄存器读取。(注:可以从 CNTVCT 寄存器中读取的虚拟计数器值就是这个值)。

Offset:对于物理计时器,以及不包含虚拟化扩展的实现中的虚拟计时器,偏移量为零。对于包含虚拟化扩展的实现中的虚拟计时器,Offset 是保存在 CNTVOFF 寄存器中的虚拟偏移量。

CompareValue:相应的 CompareValue 寄存器、CNTP_CVALCNTHP_CVALCNTV_CVAL 的值。

在此计时器视图中,计数器、偏移量和比较值都是 64 位无符号值。

这意味着可能永远不会满足 CompareValue 等于或接近 0xFFFFFFFFFFFFFFFF 的计时器的计时器条件。但是,没有实际要求使用接近计数器包装值的值。

定时器的 TimerValue 视图的操作

定时器的 TimerValue 视图作为带符号的 32downcounter 操作。一个 TimerValue 寄存器是用一个计数值编程的。这个值随着相应计数器的每一次增量而递减,当该值为零时,计时器条件就满足了。当计时器条件满足时,只有当计时器启用,且该信号在相应的计时器控制寄存器 CNTP_CTLCNTHP_CTLCNTV_CTL 中没有被屏蔽时,才会断言定时器输出信号。

注:

  • 定时器输出信号可用作电平敏感中断信号。
  • CompareValue 视图操作的伪代码说明中,EventTriggered 指示是否满足计时器条件。它不指示定时器输出信号是否被置位。

定时器的这个视图依赖于以下访问 TimerValue 寄存器的行为:

  • ReadsTimerValue = (CompareValue – (Counter - Offset))[31:0]
  • WritesCompareValue = ((Counter - Offset)[63:0] + SignExtend(TimerValue))[63:0]

其中参数具有 Operation of the CompareValue views of the timers on page B8-1966 中使用的定义,此外:

TimerValueTimerValue 寄存器的值,CNTP_TVALCNTHP_TVALCNTV_TVAL

这个定时器视图的操作是有效的:EventTriggered = (TimerValue ≤ 0)

在计时器的这个视图中,所有值都是有符号的,采用标准的 2 的补码形式。

在满足计时器条件之后,读取 TimerValue 寄存器将指示自满足该条件以来的时间。

注:将 TimerValue 编程为一个大小大于(Counter-Offset)的负数可能会导致算术溢出,从而导致 CompareValue 成为一个非常大的正值。这可能意味着在极长的一段时间内不满足计时器条件。

定时器输出信号的操作

只要满足以下所有条件,定时器输出信号就会置位:

  • 至少满足其中一个计时器条件,详细信息看 Operation of the CompareValue views of the timers on page B8-1966Operation of the TimerValue views of the timers on page B8-1967
  • 在定时器控制寄存器 CNTP_CTLCNTHP_CTLCNTV_CTL 中:
    • 启用定时器。
    • 定时器输出信号没有被屏蔽。

这意味着,要取消定时器输出信号的断言,软件必须执行以下操作之一:

  • 对计时器寄存器重新编程,以便不满足任何计时器条件。
  • 屏蔽定时器输出信号,在定时器控制寄存器中。
  • 在计时器控制寄存器中禁用计时器。

2、通用定时器寄存器摘要

B8-2 显示了包含通用计时器扩展的实现中的 CP15 寄存器。实现的寄存器集取决于实现是否也包括虚拟化扩展。
在这里插入图片描述

1、CNTVOFF 状态寄存器

通用计时器扩展的所有实现都包括虚拟计数器。因此,从概念上讲,所有实现都包括 CNTVOFF 寄存器,该寄存器定义物理计数和虚拟计数之间的虚拟偏移。在不支持虚拟化的实现中,这个偏移量为零。CNTVOFF 被定义为 PL2 模式寄存器,详细信息见 Banked PL2-mode CP15 read/write registers on page B3-1454。这意味着:

  • 在包含虚拟化扩展的实现中,CNTVOFF 是一个 RW 寄存器,当 SCR.NS 设置为 1 时,可以从非安全 Hyp 模式和从安全监视器模式访问。CNTVOFF 编码的 MCRRMRRC 未定义:
    • SCR.NS 设置为 0 时,以 Monitor 模式执行。
    • 如果不是在 Monitor 模式或 Hyp 模式下执行。
  • 在包含安全扩展但不包括虚拟化扩展的实现中,CNTVOFF 编码的 MCRRMRRC 是:
    • 如果在监视模式下执行,则不可预知,而不考虑 SCR.NS 的值。
    • 如果在非 Monitor 模式下执行,则未定义。
  • 在不包括安全扩展插件(包括任何 PMSA 实现)的实现中,尽管寄存器在概念上存在,但无法访问它。寄存器的 MCRRMRRC 指令编码未定义。

在所有 CNTVOFF 寄存器没有定义为RW寄存器的情况下,虚拟计数器使用固定的虚拟偏移值 0

二、Chapter 9:Generic Timer 翻译

本章介绍 Cortex-A7 MPCore 处理器的通用计时器。它包含以下部分:

  • 关于通用计时器
  • 通用计时器功能说明
  • 定时器编程模型

1、关于通用定时器

通用定时器可以根据递增的计数器值调度事件和触发中断。它提供了:

  • 生成定时器事件作为中断输出。
  • 生成事件流。
  • 支持虚拟化扩展。

Cortex-A7 MPCore 定时器符合 ARM 架构参考手册。

本章仅介绍特定于 Cortex-A7 MPCore 实现的功能。

2、通用计时器功能说明

Cortex-A7 MPCore 处理器为集群中的每个处理器提供了一组四个计时器。

  • 物理计时器,用于安全和非安全 PL1 模式。物理计时器的寄存器被存入以提供安全和非安全副本。
  • 虚拟计时器,用于非安全 PL1 模式。
  • 物理定时器使用在 Hyp 模式。

计数器值通过同步二进制编码的 64 位总线分发到处理器,CNTVALUEB[63:0]

A-6 中表 A-4 显示了外部中断输出引脚的信号。

3、定时器编程模型

在每个处理器中,一组定时器寄存器被分配到 CP15 协处理器空间。定时器寄存器的宽度为 32 位或 64 位宽。

9-1 显示了系统定时器寄存器。
在这里插入图片描述

三、通用定时器总结

参考博客:Linux时间子系统之(十七):ARM generic timer驱动代码分析 (wowotech.net)

1、通用定时器框架

在这里插入图片描述
上图为 ARMv7-AARMv7-R 架构使用通用定时器作为系统定时器的一个示例。

generic timer 相关硬件包括 System counterCounter interfaceTimer_xSystem events 组成。

System counter:用来记录时间的流逝,多个处理器共享。主要功能是统计输入时钟已经过了多少个 clock

Counter interfaceSystem counterTimer_x 信息交互接口。

Timer_x:用来触发 timer 事件。

System countercounter value 需要分发到各个 timer 中,也就是说,从各个 timer 的角度看,system counter value 应该是一致的。Timer 其实就是定时器,它可以定义一段指定的时间,当时间到了,就会触发一个外部的输出信号(可以输出到 GIC,作为一个 interrupt 源)。

2、System Counter 要求

1、System counter 的计数器有多少 bit

至少 56bit,和具体的实现相关。

2、输出频率范围?

典型值是 1M~50MHz

3、操作模式?

正常的时候,每个 clock 都会加一,但是,在 power saving mode 的时候,我们希望功耗可以更低一些,这时候会考虑将 system clock 的输入频率降低下来,例如降低 4 倍。为了保证 system counter 的计时是准确的,可以设定每个 clock 增加 4,而不是加1,这样 system counter 的计时仍然保持准确。

4、溢出时间?

至少 40 年。

5、精度要求?

未规定,推荐是每 24 小时在正负 10 秒的误差。

6、reset值?

0

7、是否支持 debug

可以设定 enable halt-on-debug。这个和 JTAG 调试相关。如果你使用 JTAG 调试,在单步运行的时候当然系统 counter 停下来,否则 timer 的中断就会来了,导致你无法正常的进行程序代码跟踪。

3、定时器使用

各个 cputimer 是根据 system counter 的值来触发 timer event 的,因此,系统中一定有一个机制让 System counter 的值广播到各个 CPUtimer 上,同时运行在各个 processor 上的软件可以通过接口获取 System counter 的值。

处理器可以通过 CNTPCT 寄存器来获取 system counter 的当前值,我们称之 physical counter(物理计数器) 。有 physical 就有 virtualprocessor 可以通过 CNTVCT 寄存器访问 virtual counter(虚拟计数器),不过,对于不支持 security extension(安全扩展) 和 virtualization extension(虚拟扩展) 的系统,virtual counterphysical counter 是一样的值。

系统中每个 processor 都会附着多个 timer,具体如下:

1、对于不支持 security extensionSOC(不支持 security extension 也就意味着 不支持 virtualization extension ),timer 实际上有两个,一个是 physical timer,另外一个是 virtual timer。虽然有两个,不过从行为上看,virtual timerphysical timer 行为一致。

2、对于支持 security extension 但不支持 virtualization extensionSOC,每个 cpu 有三个 timerNon-secure physical timerSecure physical timervirtual timer

3、对于支持 virtualization extensionSOC,每个 cpu 有四个 timerNon-secure PL1 physical timerSecure PL1 physical timerNon-secure PL2 physical timervirtual timer

每个 timer 都会有三个寄存器(我们用 physical timer 为例描述):

1、64-bit CompareValue register

该寄存器配合 system counter 可以实现一个 64 bit unsigned upcounter。如果 physical counter - CompareValue >= 0 的话,触发中断。也就是说,CompareValue register 其实就是一个 64 比特的 upcounter,设定为一个比当前 system counter 要大的值,随着 system counter 的不断累加,当 system counter value 触及 CompareValue register 设定的值的时候,便会向 GIC 触发中断。

2、32-bit TimerValue register

该寄存器配合 system counter 可以实现一个 32 bit signed downcounter(有的时候,使用 downcounter 会让软件逻辑更容易,看 ARM generic timer 的设计人员考虑的多么周到)。开始的时候,我们可以设定 TimerValue 寄存器的值为 1000(假设我们想 down count 1000,然后触发中断),向该寄存器写入 1000 实际上也就是设定了 CompareValue register 的值是 system counter 值加上 1000。随着 system counter 的值不断累加,TimerValue register 的值在递减,当值 <=0 的时候,便会向 GIC 触发中断。

3、32-bit控制寄存器

该寄存器主要对 timer 进行控制,具体包括:enable 或是 disabletimermask 或者 unmasktimeroutput signal(timer interrupt)

四、软件编程接口

ARM generic timer 的硬件包括两个部分:一个是每个 cputimer 硬件,另外一个就是 system levelcounter 硬件。对于每个 cputimer 硬件,使用 system control register(CP15) 来访问是最合适的,而且速度也快。要访问 system levelcounter 硬件,当然使用 memory mapped IO 的形式(请注意架构图中的 APB 总线,很多 system level 的外设都是通过 APB 访问的)。

五、Linux 内核 generic timer 相关源码分析

未完成

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值