Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Timers

1,126 views

Published on

Brief introduction to PC timers: PIT, RTC, HPET, ACPI PM Timer, Local APIC Timer, TSC. This slides also describes how to use ACPI PM Timer and Local APIC Timer.

Published in: Software
  • Be the first to comment

Timers

  1. 1. タイマー @uchan_nos 第14回 自作OSもくもく会 2019/01/20
  2. 2. 時間計測の必要性 • 時計表示 • タスク切り替え • sleep関数の実装 • 時間計測はOSを構成する基礎技術の1つ
  3. 3. パソコン用タイマーの種類 • PIT • RTC • HPET • ACPI PM Timer • Local APIC Timer • TSC
  4. 4. PIT • PIT: Programmable Interval Timer • Programmable = 周期などを設定できる • Interval = 間隔 • 「30日でできる!OS自作入門」でおなじみ • 一定周期ごとに割り込みを発生させる • ビープ音を鳴らす • レガシーデバイス
  5. 5. RTC • RTC: Real Time Clock • 日時(年月日,時分秒)を扱う時計 • バッテリバックアップされている唯一のタイマー • レガシーデバイス
  6. 6. HPET • HPET: High Precision Event Timer • High Precision = 高精度 • Event = ?(特に意味はないと思う) • 分解能が100nsより優れていることが保証されている • = 周波数が10MHz以上 • 割り込みを発生させられる • レガシーデバイス(後述)
  7. 7. ACPI PM Timer • PM: Power Management • Power Management = 電源管理 • ACPI規格で定められているタイマー • もともとはスリープ状態の時間を測るため,らしい • でも,汎用的に使える
  8. 8. Local APIC Timer • Local APIC規格で定められたタイマー • Local = CPUコア内 • APIC = Advanced Programmable Interrupt Controller • 各CPUコア内に存在する → 使用時オーバーヘッドが小さい • 割り込みを発生させられる
  9. 9. TSC • TSC: Time Stamp Counter • 各CPUコア内に存在する • CPUの動作クロックを数えるカウンタ • CPUが省電力状態になっても周波数が変わらないもの → Invariant TSC
  10. 10. タイマーまとめ 名前 周波数 割り込み レガシー PIT 1.193182MHz 可 レガシー RTC 32.768KHz 可 レガシー HPET 機種依存,レジスタから取得可 可 レガシー ACPI PM Timer 3.579545MHz 不可 Local APIC Timer 機種依存,取得不可 可 TSC 機種依存,取得不可 不可 Invariant TSC 機種依存,レジスタから取得可 不可
  11. 11. レガシーデバイス • Legacy = 遺産 • 現代におけるレガシーデバイスの定義(筆者独自の定義) • 存在をシステマチックに確かめる術がないもの • レジスタにアクセスしてみないとデバイスの有無が分からない • 電源管理できないもの • 省電力モードでも常に動き続ける • この定義で行けばHPETはレガシーではないが…
  12. 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. 13. XSDTを確認してみる • XSDT = ACPIのルートテーブル • NシリーズCerelon搭載パソコン • CPU: Celeron N3050 • PC名: Shuttle XS36V5 • 確かにHPETがXSDTに無い! • ちなみにQEMUでは FACP, APIC, HPET, BGRT が見える
  14. 14. 筆者おすすめの組み合わせ • 初期計時:ACPI PM Timer • 普段使い:Local APIC Timer • ACPI PM Timerは規格ではオプショナルだが事実上標準ぽい • https://japan.zdnet.com/article/20365868/ • 「ACPI対応のマザーボードであれば、このタイマーが提供される。」 • Local APIC TimerはIntel SDMに載っている標準デバイス
  15. 15. 初期計時のためのタイマー選定 1/2 • 最初から動作周波数が分かっているタイマーを使って Local APIC Timerの周波数を測りたい • 動作周波数が既知のタイマー • PIT • RTC • HPET • ACPI PM Timer • Invariant TSC • なるべく分解能が優れ,レガシーでないタイマーを選びたい
  16. 16. 初期計時のためのタイマー選定 2/2 • レガシーでない,周波数が既知のタイマー • ACPI PM Timer • Invariant TSC • Invariant TSCはレジスタから周波数を取得できるが, BIOSの設定によってはズレることがある • Bus Clockを変更するとズレる • CPUによってはTSCがInvariantではない • ということで,ACPI PM Timerを選ぶのをおすすめする
  17. 17. 普段使いのためのタイマー選定 • 割り込みに対応したタイマーの中で, 動作オーバーヘッドが小さいものを使いたい • 割り込みに対応したタイマー • PIT • RTC • HPET • Local APIC Timer • この中でレガシーでないのはLocal APIC Timerのみ • 動作オーバーヘッドが最も小さいのもLocal APIC Timer
  18. 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
  19. 19. ACPI PM Timerの使い方 UEFIで起動してからタイマーで時間を測るまでの道のり
  20. 20. 大まかな流れ • ACPIのXSDTを得る • XSDTからFADTを探す • FADTのPM_TMR_BLKレジスタを読む • TMR_VALレジスタを読む
  21. 21. XSDTを得る • ACPIのXSDTを取得する • UEFI環境での方法は大神さんの同人誌が参考になる • 『フルスクラッチで作る!x86_64自作OS パート2』 http://yuma.ohgami.jp/x86_64-Jisaku-OS-2/01_acpi.html • ざっくり言うと • EFI_SYSTEM_TABLE • → EFI_CONFIGURATION_TABLE • → RSDP • → XSDT
  22. 22. XSDTからFADTを探す • FADTのシグネチャは”FACP” • テーブル名とシグネチャが異なるので注意! • XSDTは64ビットアドレスの配列 • 順にアドレスが指す先を読んでFADTを探す
  23. 23. ACPI Specification, Version 6.2 Errata Aより Sig = “FACP”である ディスクリプタを探す
  24. 24. FADTのPM_TMR_BLKレジスタを読む • FADTの位置が分かればPM_TMR_BLKレジスタを読める • PM_TMR_BLKはFADT先頭から76バイト目
  25. 25. ACPI Specification, Version 6.2 Errata Aより
  26. 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. 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ビット以上に ならないように 注意
  28. 28. Local APIC Timerの使い方
  29. 29. LVT Timerレジスタを設定 • LVT Timerレジスタ = FEE0 0320H • ビット18:17でモードを設定 • 00b: One-shotモード • 01b: Periodicモード • 10b: TSC-deadlineモード • 他のビットは割り込み関係の設定. • ビット16を1にしておくと割り込みが発生しない.
  30. 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”
  31. 31. Periodicモード Initial Countレジスタ に値Nを書き込む Current Countレジスタの値 0 N 時刻 割り込み 割り込み
  32. 32. 補足: レジスタアドレスの謎 • Local APIC Timer関連のレジスタはアドレス固定 • Initial Countレジスタ = FEE0 0380H • LVT Timerレジスタ = FEE0 0320H • しかし,Local APIC Timerは各コア毎に存在するはず • 同じアドレスなのに,なぜ区別できるのだろうか
  33. 33. CPUコア1 Initial Count メモリバス FEE0 0320 DDR SDRAM EAX mov [eax], ebx LVT Timer アドレスデコーダ 0003 0000EBX FEE0 0000H - FEE0 0400H CPUコアN Local APICレジスタへのアクセスは CPUコア内部で完結する →同じアドレスでも競合しない

×