# 機能設計書 57-ACPIサポート

## 概要

本ドキュメントは、FreeBSDにおけるACPI（Advanced Configuration and Power Interface）サポートの設計を記述する。ACPIはハードウェア構成の検出、電力管理、サーマル管理等を提供するプラットフォーム標準規格の実装である。

### 本機能の処理概要

ACPIサポートは、ACPI仕様に基づくハードウェアの構成情報取得、電力状態管理、サーマルゾーン管理、デバイス列挙、割り込みルーティング等を行う。ACPICAインタプリタを用いてACPIテーブル（DSDT/SSDT）のAML（ACPI Machine Language）を解釈し、プラットフォーム固有のハードウェア制御を実現する。

**業務上の目的・背景**：現代のx86/x64システムはACPIをプラットフォーム管理の標準としており、デバイス検出、電力管理（スリープ/ハイバネーション）、CPU周波数制御、温度監視等にACPIが不可欠である。ARM系プラットフォームでもACPIの採用が進んでいる。

**機能の利用シーン**：システム起動時のハードウェア検出、電源ボタン/蓋閉じイベントの処理、CPU省電力制御、バッテリ状態監視、サーマルスロットリング、PCIデバイスの割り込みルーティング。

**主要な処理内容**：
1. ACPIテーブルの解析とACPICAインタプリタの初期化
2. ACPIデバイスツリーの構築と列挙
3. 電源ボタン・蓋スイッチイベント処理
4. バッテリ状態監視（CMBATドライバ）
5. AC電源アダプタ状態監視（ACADドライバ）
6. CPU電力状態（C-state）管理
7. CPU周波数スケーリング（P-state）管理
8. サーマルゾーン管理
9. PCI割り込みルーティング
10. Embedded Controller（EC）との通信
11. HPETタイマー管理
12. ACPIドック/ホットプラグサポート

**関連システム・外部連携**：PCI/PCIeサブシステム（割り込みルーティング）、電源管理フレームワーク（powerd）、devd（イベント通知）、sysctl（設定・状態参照）との連携。

**権限による制御**：カーネルドライバとして動作。acpiconfユーザ空間ツールによるACPI制御にはroot権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | （カーネルドライバのため関連画面なし） | - | - |

## 機能種別

プラットフォーム管理 / 電力管理 / デバイス列挙

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ACPIテーブル | RSDP/RSDT/XSDT/DSDT/SSDT | Yes | ファームウェア提供のACPIテーブル | ACPI署名チェック |
| AMLバイトコード | byte[] | Yes | ACPIメソッドの実行コード | ACPICAインタプリタで検証 |
| acpiconfコマンド | ioctl | No | ユーザ空間からの制御リクエスト | 有効なACPI ioctl |

### 入力データソース

- ファームウェア（BIOS/UEFI）提供のACPIテーブル
- ハードウェアレジスタ（EC、GPE等）
- ユーザ空間ツール（acpiconf、acpidump）
- sysctl設定

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| デバイスツリー | device tree | ACPIデバイスの階層構造 |
| 電力状態通知 | event | スリープ/ウェイク/シャットダウンイベント |
| バッテリ状態 | sysctl | バッテリ残量、充電状態 |
| サーマル情報 | sysctl | 温度、閾値 |

### 出力先

- newbus（デバイスツリー）
- devd（電源イベント通知）
- sysctl（hw.acpi.*）
- dmesg（ACPIログ）

## 処理フロー

### 処理シーケンス

```
1. ACPIテーブル検出
   └─ RSDP/RSDT/XSDTの探索とマッピング
2. ACPICAインタプリタ初期化
   └─ AcpiInitializeSubsystem(), AcpiLoadTables()
3. DSDT/SSDT解析
   └─ AMLバイトコードの解析、名前空間構築
4. ACPIデバイス列挙
   └─ デバイスツリー走査、子デバイスのprobe/attach
5. GPE（General Purpose Event）ハンドラ登録
   └─ 電源ボタン、蓋スイッチ等のイベントハンドラ
6. EC初期化
   └─ Embedded Controllerとの通信チャネル確立
7. サーマルゾーン初期化
   └─ 温度監視、閾値設定
8. イベント処理ループ
   └─ GPEイベント、Notify等の非同期処理
```

### フローチャート

```mermaid
flowchart TD
    A[RSDP探索] --> B[ACPIテーブルマッピング]
    B --> C[ACPICA初期化]
    C --> D[DSDT/SSDT解析]
    D --> E[名前空間構築]
    E --> F[ACPIデバイス列挙]
    F --> G[GPEハンドラ登録]
    G --> H[EC初期化]
    H --> I[サーマルゾーン初期化]
    I --> J[イベント待ち受け]
    J --> K{イベント種別}
    K -->|電源ボタン| L[シャットダウン/スリープ]
    K -->|蓋スイッチ| M[サスペンド]
    K -->|サーマル| N[スロットリング]
    K -->|バッテリ| O[状態更新]
    L --> J
    M --> J
    N --> J
    O --> J
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-57-01 | Quirk適用 | 既知のBIOS/ACPIバグに対して回避策を適用 | システム起動時、acpi_quirks参照 |
| BR-57-02 | スリープ状態遷移 | S3（Suspend to RAM）、S4（Hibernate）、S5（Soft Off）の状態遷移 | 電源イベント時 |
| BR-57-03 | CPU電力制御 | C-state/P-stateによるCPU省電力制御 | アイドル時/負荷変動時 |
| BR-57-04 | PCI割り込みルーティング | _PRT（PCI Routing Table）メソッドによる割り込み割り当て | PCIデバイス初期化時 |

### 計算ロジック

サーマルスロットリング: 温度がPassive Cooling閾値を超えた場合、CPU周波数を段階的に低下。Critical Temperature到達時は緊急シャットダウン。

## データベース操作仕様

該当なし（カーネルドライバ）。

### テーブル別操作詳細

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| AE_NOT_FOUND | テーブル不存在 | ACPIテーブルが見つからない | ACPIなしで起動（レガシーモード） |
| AE_BAD_DATA | データ不正 | ACPIテーブルのチェックサムエラー | Quirk適用または無視 |
| AE_AML_ERROR | AML実行エラー | AMLメソッド実行時のエラー | エラーログ記録、処理継続 |

### リトライ仕様

ECとの通信はタイムアウト付きリトライ。AMLメソッド実行エラーは記録し処理を継続。

## トランザクション仕様

該当なし。

## パフォーマンス要件

- ACPIテーブル解析はブート時に1回実行（通常数百ミリ秒）
- GPEイベント処理は割り込みコンテキストで低レイテンシ
- EC通信はポーリングベース（数ミリ秒のレイテンシ）

## セキュリティ考慮事項

- ACPIテーブルはファームウェアから取得するため、ファームウェアの信頼性に依存
- AMLバイトコードはカーネル空間で実行されるため、不正なAMLはセキュリティリスクとなりうる
- acpiconf操作にはroot権限が必要

## 備考

- FreeBSDのACPIサポートはACPICA（Intel提供のACPIコンポーネントアーキテクチャ）を使用
- ACPICAはcontrib/dev/acpica/に配置
- FreeBSD固有のOSL（OS Service Layer）実装がsys/dev/acpica/に存在
- acpi_quirks（sys/dev/acpica/acpi_quirks）に既知BIOSバグの回避策が定義

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | acpivar.h | `sys/dev/acpica/acpivar.h` | FreeBSD ACPI構造体定義 |
| 1-2 | acpiio.h | `sys/dev/acpica/acpiio.h` | ACPI ioctl定義 |

#### Step 2: ACPIコアドライバを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | acpi.c | `sys/dev/acpica/acpi.c` | ACPIコアドライバ（メインファイル） |

**主要処理フロー**:
1. **34-36行目**: opt_acpi.hインクルード（ACPI構成オプション）
2. **37-57行目**: カーネルヘッダインクルード群
3. **72-74行目**: ACPICAヘッダ（acpi.h, accommon.h, acnamesp.h）
4. **76-77行目**: FreeBSD ACPI変数・ioctl定義ヘッダ
5. **79行目**: PCI変数ヘッダ（PCI割り込みルーティング連携）

#### Step 3: 個別ACPIドライバを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | acpi_button.c | `sys/dev/acpica/acpi_button.c` | 電源ボタン/スリープボタン |
| 3-2 | acpi_lid.c | `sys/dev/acpica/acpi_lid.c` | 蓋スイッチ |
| 3-3 | acpi_cmbat.c | `sys/dev/acpica/acpi_cmbat.c` | バッテリ |
| 3-4 | acpi_acad.c | `sys/dev/acpica/acpi_acad.c` | AC電源アダプタ |
| 3-5 | acpi_cpu.c | `sys/dev/acpica/acpi_cpu.c` | CPU電力管理 |
| 3-6 | acpi_ec.c | `sys/dev/acpica/acpi_ec.c` | Embedded Controller |
| 3-7 | acpi_hpet.c | `sys/dev/acpica/acpi_hpet.c` | HPETタイマー |

### プログラム呼び出し階層図

```
ACPI nexus ドライバ (acpi.c)
    |
    +-- acpi_probe() / acpi_attach()
    |   +-- AcpiInitializeSubsystem() [ACPICA]
    |   +-- AcpiLoadTables() [ACPICA]
    |   +-- AcpiEnableSubsystem() [ACPICA]
    |   +-- acpi_probe_children() (デバイス列挙)
    |
    +-- 子デバイスドライバ
        +-- acpi_button.c (電源ボタン)
        +-- acpi_lid.c (蓋スイッチ)
        +-- acpi_cmbat.c (バッテリ)
        +-- acpi_acad.c (AC電源)
        +-- acpi_cpu.c (CPU電力)
        +-- acpi_ec.c (EC通信)
        +-- acpi_hpet.c (HPETタイマー)
        +-- acpi_pci_link.c (PCI割り込みリンク)
        +-- acpi_perf.c (CPU周波数制御)
        +-- acpi_powerres.c (電力リソース)
```

### データフロー図

```
[入力]                    [処理]                         [出力]

ACPIテーブル  ────▶ ACPICA インタプリタ        ────▶ デバイスツリー
(RSDP/DSDT/SSDT)    AcpiLoadTables()                  (newbus子デバイス)
                    AcpiEvaluateObject()

GPEイベント   ────▶ acpi_event_handler()       ────▶ devd通知
(ハードウェア割り込み)  Notify処理                      sysctl更新

acpiconf     ────▶ acpi_ioctl()               ────▶ 電力状態遷移
(ユーザ空間)       AcpiEnterSleepState()              ハードウェア制御
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| acpi.c | `sys/dev/acpica/acpi.c` | ソース | ACPIコアドライバ |
| acpivar.h | `sys/dev/acpica/acpivar.h` | ヘッダ | ACPI変数定義 |
| acpiio.h | `sys/dev/acpica/acpiio.h` | ヘッダ | ACPI ioctl定義 |
| acpi_button.c | `sys/dev/acpica/acpi_button.c` | ソース | 電源ボタン |
| acpi_lid.c | `sys/dev/acpica/acpi_lid.c` | ソース | 蓋スイッチ |
| acpi_cmbat.c | `sys/dev/acpica/acpi_cmbat.c` | ソース | バッテリ |
| acpi_acad.c | `sys/dev/acpica/acpi_acad.c` | ソース | AC電源 |
| acpi_cpu.c | `sys/dev/acpica/acpi_cpu.c` | ソース | CPU電力管理 |
| acpi_ec.c | `sys/dev/acpica/acpi_ec.c` | ソース | Embedded Controller |
| acpi_hpet.c | `sys/dev/acpica/acpi_hpet.c` | ソース | HPETタイマー |
| acpi_pci.c | `sys/dev/acpica/acpi_pci.c` | ソース | PCI ACPI連携 |
| acpi_pci_link.c | `sys/dev/acpica/acpi_pci_link.c` | ソース | PCI割り込みリンク |
| acpi_perf.c | `sys/dev/acpica/acpi_perf.c` | ソース | CPU周波数制御 |
| acpi_quirk.c | `sys/dev/acpica/acpi_quirk.c` | ソース | Quirk管理 |
| acpi_quirks | `sys/dev/acpica/acpi_quirks` | データ | Quirkデータベース |
| acpi_resource.c | `sys/dev/acpica/acpi_resource.c` | ソース | リソース管理 |
