Timers4. PIT
• PIT: Programmable Interval Timer
• Programmable = 周期などを設定できる
• Interval = 間隔
• 「30日でできる!OS自作入門」でおなじみ
• 一定周期ごとに割り込みを発生させる
• ビープ音を鳴らす
• レガシーデバイス
5. RTC
• RTC: Real Time Clock
• 日時(年月日,時分秒)を扱う時計
• バッテリバックアップされている唯一のタイマー
• レガシーデバイス
6. HPET
• HPET: High Precision Event Timer
• High Precision = 高精度
• Event = ?(特に意味はないと思う)
• 分解能が100nsより優れていることが保証されている
• = 周波数が10MHz以上
• 割り込みを発生させられる
• レガシーデバイス(後述)
7. ACPI PM Timer
• PM: Power Management
• Power Management = 電源管理
• ACPI規格で定められているタイマー
• もともとはスリープ状態の時間を測るため,らしい
• でも,汎用的に使える
8. Local APIC Timer
• Local APIC規格で定められたタイマー
• Local = CPUコア内
• APIC = Advanced Programmable Interrupt Controller
• 各CPUコア内に存在する
→ 使用時オーバーヘッドが小さい
• 割り込みを発生させられる
9. TSC
• TSC: Time Stamp Counter
• 各CPUコア内に存在する
• CPUの動作クロックを数えるカウンタ
• CPUが省電力状態になっても周波数が変わらないもの
→ Invariant TSC
10. タイマーまとめ
名前 周波数 割り込み レガシー
PIT 1.193182MHz 可 レガシー
RTC 32.768KHz 可 レガシー
HPET 機種依存,レジスタから取得可 可 レガシー
ACPI PM Timer 3.579545MHz 不可
Local APIC Timer 機種依存,取得不可 可
TSC 機種依存,取得不可 不可
Invariant TSC 機種依存,レジスタから取得可 不可
11. レガシーデバイス
• Legacy = 遺産
• 現代におけるレガシーデバイスの定義(筆者独自の定義)
• 存在をシステマチックに確かめる術がないもの
• レジスタにアクセスしてみないとデバイスの有無が分からない
• 電源管理できないもの
• 省電力モードでも常に動き続ける
• この定義で行けばHPETはレガシーではないが…
12. HPETはレガシーデバイスか
• “N-series Intel Pentium Processors and Intel Celeron
Processors Datasheet - Volume 1 of 3”, Feb. 2016
• によれば,NシリーズのPentiumおよびCeleronでは
HPETはPCU-iLB内に存在
• PCU = Platform Controller Unit
• iLB = The Intel Legacy Block
• iLBは8259 PIC, I/O-APIC, 8254 PIT, HPET, RTCを含む
• → HPETはレガシーデバイスの仲間!
13. XSDTを確認してみる
• XSDT = ACPIのルートテーブル
• NシリーズCerelon搭載パソコン
• CPU: Celeron N3050
• PC名: Shuttle XS36V5
• 確かにHPETがXSDTに無い!
• ちなみにQEMUでは
FACP, APIC, HPET, BGRT が見える
14. 筆者おすすめの組み合わせ
• 初期計時:ACPI PM Timer
• 普段使い:Local APIC Timer
• ACPI PM Timerは規格ではオプショナルだが事実上標準ぽい
• https://japan.zdnet.com/article/20365868/
• 「ACPI対応のマザーボードであれば、このタイマーが提供される。」
• Local APIC TimerはIntel SDMに載っている標準デバイス
16. 初期計時のためのタイマー選定 2/2
• レガシーでない,周波数が既知のタイマー
• ACPI PM Timer
• Invariant TSC
• Invariant TSCはレジスタから周波数を取得できるが,
BIOSの設定によってはズレることがある
• Bus Clockを変更するとズレる
• CPUによってはTSCがInvariantではない
• ということで,ACPI PM Timerを選ぶのをおすすめする
18. タイマーの接続図
CPUコア
Local APIC Timer
Platform Controller Hub
ACPI PM Timer
バス
• Local APIC Timer, TSC
• CPUコア内に実装されている
• PIT, RTC, HPET, ACPI PM Timer
• CPU外に実装されている
• アーキテクチャ依存の場所
• Intel 5シリーズ以降はPCH内
TSC
RTCPIT HPET
26. TMR_VALレジスタを読む
• PM_TMR_BLKはACPI PM Timer関連の
レジスタブロックを指すアドレス
• PM_TMR_BLKの説明に“System port address”とある
• メモリアドレスではなくI/Oポートのアドレスである
• movではなく,in命令で読む
• uint32_t pm_tmr_blk = *(uint32_t*)(fadt_addr + 76);
• uint32_t tmr_val = io_in32(pm_tmr_blk);
27. TMR_VALレジスタ
• 3.579545MHzでカウントアップし続ける
• 24ビットで1周 = 約4.69秒で1周
• 時間を測るにはこんな風にする(1秒測る例)
• uint32_t initial_val = io_in32(pm_tmr_blk);
• uint32_t target_val = initial_val + 3579545;
• While (io_in32(pm_tmr_blk) < target_val);
target_valが
24ビット以上に
ならないように
注意
29. LVT Timerレジスタを設定
• LVT Timerレジスタ = FEE0 0320H
• ビット18:17でモードを設定
• 00b: One-shotモード
• 01b: Periodicモード
• 10b: TSC-deadlineモード
• 他のビットは割り込み関係の設定.
• ビット16を1にしておくと割り込みが発生しない.
30. Initial Countレジスタを設定
• Initial Countレジスタ = FEE0 0380H
• 0より大きな値を書くとタイマーの動作開始
• One-shotモード
• 値がCurrent Countレジスタにコピーされ,
Current Countレジスタがカウントダウンされる
• Periodicモード
• Current Countレジスタが0になると割り込み発生後,
Initial Countレジスタから値が再設定される
• 詳しくはIntel SDM Vol.3, “10.5.4 APIC Timer”
32. 補足: レジスタアドレスの謎
• Local APIC Timer関連のレジスタはアドレス固定
• Initial Countレジスタ = FEE0 0380H
• LVT Timerレジスタ = FEE0 0320H
• しかし,Local APIC Timerは各コア毎に存在するはず
• 同じアドレスなのに,なぜ区別できるのだろうか