|
| 1 | +この章では、APIC Timerドライバについて記述します。 |
| 2 | +実装されているファイルは[apic.c](https://github.com/nekogakure/LiteCore/blob/main/src/kernel/driver/timer/apic.c), [apic.h](https://github.com/nekogakure/LiteCore/blob/main/src/include/driver/timer/apic.h)です。 |
| 3 | + |
| 4 | +## 概要 |
| 5 | +APIC (Advanced Programmable Interrupt Controller) Timerは、x86_64プロセッサに内蔵された高精度タイマーです。このドライバは、APIC Timerを使用してシステム時刻の管理、タイマー割り込みの生成、および遅延処理を実装します。ACPI PM Timerを使用してキャリブレーションを行い、正確な周波数を計算します。 |
| 6 | + |
| 7 | +## 関数 / API |
| 8 | + |
| 9 | +#### `int apic_timer_init(void)` |
| 10 | +APIC Timerを初期化します。CPUのAPICサポートを確認し、ベースアドレスを取得し、タイマー周波数をキャリブレーションして、1000Hz (1ms間隔) で動作するように設定します。 |
| 11 | + |
| 12 | +引数: なし |
| 13 | + |
| 14 | +戻り値: 0=成功、-1=APICサポートなし |
| 15 | + |
| 16 | +#### `int apic_timer_available(void)` |
| 17 | +APIC Timerが初期化済みで利用可能かチェックします。 |
| 18 | + |
| 19 | +引数: なし |
| 20 | + |
| 21 | +戻り値: 1=利用可能、0=利用不可 |
| 22 | + |
| 23 | +#### `void apic_timer_tick(uint32_t irq, void *context)` |
| 24 | +タイマー割り込みハンドラです。1ms毎に呼ばれ、ティックカウントを増加させます。EOI (End of Interrupt) を送信して割り込みを終了します。 |
| 25 | + |
| 26 | +引数: |
| 27 | + - irq(uint32_t): 割り込み番号 |
| 28 | + - context(void*): コンテキスト(未使用) |
| 29 | + |
| 30 | +#### `uint64_t apic_get_uptime_us(void)` |
| 31 | +システム起動からの経過時間をマイクロ秒で取得します。 |
| 32 | + |
| 33 | +引数: なし |
| 34 | + |
| 35 | +戻り値: 経過時間(マイクロ秒) |
| 36 | + |
| 37 | +#### `uint64_t apic_get_uptime_ms(void)` |
| 38 | +システム起動からの経過時間をミリ秒で取得します。 |
| 39 | + |
| 40 | +引数: なし |
| 41 | + |
| 42 | +戻り値: 経過時間(ミリ秒) |
| 43 | + |
| 44 | +#### `uint32_t apic_timer_get_frequency(void)` |
| 45 | +APIC Timerの周波数を取得します。 |
| 46 | + |
| 47 | +引数: なし |
| 48 | + |
| 49 | +戻り値: タイマー周波数(Hz) |
| 50 | + |
| 51 | +#### `void apic_timer_delay_us(uint32_t us)` |
| 52 | +指定されたマイクロ秒だけビジーウェイトで遅延します。 |
| 53 | + |
| 54 | +引数: |
| 55 | + - us(uint32_t): 遅延時間(マイクロ秒) |
| 56 | + |
| 57 | +#### `void apic_timer_delay_ms(uint32_t ms)` |
| 58 | +指定されたミリ秒だけビジーウェイトで遅延します。 |
| 59 | + |
| 60 | +引数: |
| 61 | + - ms(uint32_t): 遅延時間(ミリ秒) |
| 62 | + |
| 63 | +## 定数 / 定義 |
| 64 | + |
| 65 | +- `APIC_BASE_DEFAULT`: 0xFEE00000 - APICレジスタのデフォルトベースアドレス |
| 66 | +- `APIC_ID`: 0x020 - Local APIC IDレジスタオフセット |
| 67 | +- `APIC_VERSION`: 0x030 - Local APIC Versionレジスタオフセット |
| 68 | +- `APIC_TPR`: 0x080 - Task Priority Registerオフセット |
| 69 | +- `APIC_EOI`: 0x0B0 - End Of Interruptレジスタオフセット |
| 70 | +- `APIC_LDR`: 0x0D0 - Logical Destination Registerオフセット |
| 71 | +- `APIC_DFR`: 0x0E0 - Destination Format Registerオフセット |
| 72 | +- `APIC_SPURIOUS`: 0x0F0 - Spurious Interrupt Vector Registerオフセット |
| 73 | +- `APIC_ESR`: 0x280 - Error Status Registerオフセット |
| 74 | +- `APIC_TIMER_LVT`: 0x320 - LVT Timer Registerオフセット |
| 75 | +- `APIC_TIMER_INIT`: 0x380 - Timer Initial Countレジスタオフセット |
| 76 | +- `APIC_TIMER_CURRENT`: 0x390 - Timer Current Countレジスタオフセット |
| 77 | +- `APIC_TIMER_DIV`: 0x3E0 - Timer Divide Configurationレジスタオフセット |
| 78 | +- `APIC_TIMER_MODE_ONESHOT`: 0x00000000 - ワンショットモード |
| 79 | +- `APIC_TIMER_MODE_PERIODIC`: 0x00020000 - 周期モード |
| 80 | +- `APIC_TIMER_MODE_TSCDEADLINE`: 0x00040000 - TSCデッドラインモード |
| 81 | +- `APIC_TIMER_DIV_1`: 0x0B - 分周比1 |
| 82 | +- `APIC_TIMER_DIV_2`: 0x00 - 分周比2 |
| 83 | +- `APIC_TIMER_DIV_4`: 0x01 - 分周比4 |
| 84 | +- `APIC_TIMER_DIV_8`: 0x02 - 分周比8 |
| 85 | +- `APIC_TIMER_DIV_16`: 0x03 - 分周比16 |
| 86 | +- `APIC_TIMER_DIV_32`: 0x08 - 分周比32 |
| 87 | +- `APIC_TIMER_DIV_64`: 0x09 - 分周比64 |
| 88 | +- `APIC_TIMER_DIV_128`: 0x0A - 分周比128 |
| 89 | +- `ACPI_PM_TIMER_PORT`: 0x608 - ACPI PM Timerのポートアドレス |
| 90 | +- `ACPI_PM_TIMER_FREQ`: 3579545 - ACPI PM Timerの固定周波数(3.579545 MHz) |
| 91 | + |
| 92 | +## 構造体 |
| 93 | + |
| 94 | +このファイルには公開構造体の定義はありません。 |
| 95 | + |
| 96 | +## 実装の詳細 |
| 97 | + |
| 98 | +### キャリブレーション |
| 99 | +APIC Timerの周波数は CPU によって異なるため、ACPI PM Timer(固定3.579545 MHz)を基準にしてキャリブレーションを行います。10ms間のAPICタイマーのカウント数を測定し、実際の周波数を計算します。 |
| 100 | + |
| 101 | +### 動作モード |
| 102 | +APIC TimerはPeriodicモードで動作し、1000Hz(1ms間隔)で割り込みを生成します。割り込みベクタは48番が使用されます。 |
| 103 | + |
| 104 | +### 時刻管理 |
| 105 | +`current_tick_count`変数で1ms単位のティック数を管理し、これを基にマイクロ秒/ミリ秒単位の経過時間を提供します。 |
| 106 | + |
| 107 | +### 遅延処理 |
| 108 | +`apic_timer_delay_us()`および`apic_timer_delay_ms()`は、アップタイムを監視してビジーウェイトで遅延を実装します。CPUの負荷を避けるため`pause`命令を使用します。 |
0 commit comments