# 通知設計書 21-PMU lid close

## 概要

本ドキュメントは、FreeBSDカーネルにおけるPMU（Power Management Unit）のノートPC蓋閉じ通知「PMU lid close」の設計仕様を記述する。Apple PowerMac/PowerBookプラットフォームにおいて、ノートPCの蓋（lid）が閉じられた際にdevctl_notifyを通じてユーザーランドのdevd(8)デーモンへ通知を発行する仕組みである。

### 本通知の処理概要

本通知は、Apple PowerMacプラットフォームのPMU（Power Management Unit）コントローラが、ノートPCの蓋が閉じられたことを検出した際にカーネルからユーザーランドへ通知するためのdevctl通知イベントである。

**業務上の目的・背景**：ノートPCの蓋が閉じられた際に、システムはスリープ状態への移行やディスプレイの消灯などの電源管理アクションを実行する必要がある。devdデーモンがこの通知を受け取ることで、ユーザーが設定したスクリプト（例: /etc/devd.conf内のルール）を実行し、サスペンドやディスプレイロックなどの適切なアクションを自動的にトリガーできるようになる。

**通知の送信タイミング**：PMUからの環境割り込み（PMU_INT_ENVIRONMENT）を受信し、割り込み応答のresp[2]にPMU_ENV_LID_CLOSED（0x01）ビットがセットされており、かつ前回の状態が蓋が開いていた状態（sc->lid_closed == 0）であった場合に送信される。つまり、蓋が閉じられた瞬間（状態遷移）にのみ送信される。

**通知の受信者**：ユーザーランドのdevd(8)デーモンが受信する。devdはdevctl_notify経由で/dev/devctlデバイスからイベントを読み取り、/etc/devd.confに記述されたマッチングルールに基づいて対応するアクションスクリプトを実行する。

**通知内容の概要**：システム名「PMU」、サブシステム名「lid」、タイプ「close」の3つの文字列で構成される。追加データ（data引数）はNULLであり、付随情報は含まれない。

**期待されるアクション**：受信者（devd）は、この通知に基づいてシステムのスリープ（サスペンド）処理の開始、ディスプレイのロック、バックライトの消灯、外部モニタの切断処理などを実行することが期待される。

## 通知種別

カーネルdevctl通知（devctl_notify経由のデバイスイベント通知）。devd(8)デーモンが/dev/devctlを介して受信するカーネル内通知メカニズムである。

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 非同期（割り込みハンドラからdevctl_notifyを呼び出し） |
| 優先度 | 高（ハードウェア割り込みレベルで処理） |
| リトライ | 無（カーネル通知は一度のみ発行） |

### 送信先決定ロジック

devctl_notifyはカーネル内の通知キューにイベントを追加する。devd(8)デーモンが/dev/devctlデバイスを通じてこのキューを監視・読み取りする。送信先は固定であり、動的な宛先決定ロジックは存在しない。

## 通知テンプレート

### devctl通知の場合

| 項目 | 内容 |
|-----|------|
| システム名 | PMU |
| サブシステム名 | lid |
| タイプ | close |
| 追加データ | NULL（なし） |

### 本文テンプレート

```
!system=PMU subsystem=lid type=close
```

### 添付ファイル

該当なし（カーネル通知のため添付ファイルの概念はない）。

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| system | 通知のシステム名 | 固定値 "PMU" | Yes |
| subsystem | 通知のサブシステム名 | 固定値 "lid" | Yes |
| type | 通知タイプ | 固定値 "close" | Yes |
| data | 追加情報 | NULL | No |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| ハードウェア割り込み | PMU環境割り込み（PMU_INT_ENVIRONMENT） | resp[2] & PMU_ENV_LID_CLOSED かつ !sc->lid_closed | PMUから蓋閉じ状態が検出され、前回が開いていた場合のみ通知 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| sc->lid_closed == 1 | 既に蓋が閉じた状態として記録されている場合、重複通知を抑止する |
| PMU_INT_ENVIRONMENT未設定 | 環境割り込みビットがない場合はlid状態をチェックしない |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[PMU割り込み発生] --> B[pmu_intr関数呼び出し]
    B --> C[PMU_INT_ACK送信・応答取得]
    C --> D{resp[1] & PMU_INT_ENVIRONMENT?}
    D -->|No| E[終了]
    D -->|Yes| F{resp[2] & PMU_ENV_LID_CLOSED?}
    F -->|No| E
    F -->|Yes| G{sc->lid_closed == 0?}
    G -->|No| E
    G -->|Yes| H[sc->lid_closed = 1]
    H --> I[devctl_notify PMU lid close NULL]
    I --> E
```

## データベース参照・更新仕様

### 参照テーブル一覧

該当なし（カーネルドライバのためデータベースは使用しない）。

### 更新テーブル一覧

該当なし。ただしカーネル内のソフトコンテキスト構造体（struct pmu_softc）のlid_closedフィールドを1に更新する。

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 割り込み応答なし | PMU_INT_ACKの応答長が1未満またはresp[1]が0 | 何もせず関数からリターン |
| devctl_notify失敗 | devctlキューが満杯の場合 | カーネル内でイベントを破棄（ログ出力なし） |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0（リトライなし） |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし（状態遷移時のみ発火するため実質1回） |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし。ハードウェアイベント駆動のため常時有効。

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

- /dev/devctlデバイスへのアクセスにはroot権限が必要であり、一般ユーザーは通知を直接読み取れない
- devd(8)はroot権限で動作するため、通知に応じて実行されるスクリプトもroot権限で動作する点に注意
- 通知データにNULLが渡されるため、個人情報や機密情報の漏洩リスクはない

## 備考

- この通知はApple PowerMac99プラットフォーム（PowerBook G3/G4等）専用であり、x86/amd64プラットフォームでは発行されない
- x86プラットフォームではACPIサブシステムが同等のlid状態変更通知を提供する
- 対となるlid open通知（No.22）と排他的に動作し、lid_closedフラグによって状態が管理される

---

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

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

### 推奨読解順序

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

まず、PMUドライバのソフトコンテキスト構造体とPMU関連定数の定義を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | pmuvar.h | `sys/powerpc/powermac/pmuvar.h` | struct pmu_softcのlid_closedフィールド（行163）、PMU_ENV_LID_CLOSED定数（行101）、PMU_INT_ENVIRONMENT定数（行84） |

**読解のコツ**: pmuvar.hはPMUドライバの全ての定数定義と構造体を含む。PMU_ENV_LID_CLOSED（0x01）は蓋閉じ状態のビットマスクであり、PMU_INT_ENVIRONMENT（0x40）は環境変化割り込みのビットマスクである。

#### Step 2: エントリーポイントを理解する

PMU割り込みハンドラが通知発行のエントリーポイントとなる。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | pmu.c | `sys/powerpc/powermac/pmu.c` | pmu_intr関数（行696-757）が割り込みハンドラ |

**主要処理フロー**:
1. **行710**: vIFRレジスタをクリアして割り込みを確認応答
2. **行711**: PMU_INT_ACKコマンドで割り込み内容を取得
3. **行743**: resp[1] & PMU_INT_ENVIRONMENTで環境割り込みを判定
4. **行745**: PMU_ENV_LID_CLOSEDビットと前回状態sc->lid_closedを確認
5. **行746**: sc->lid_closedを1に設定
6. **行747**: devctl_notify("PMU", "lid", "close", NULL)を呼び出し

#### Step 3: 割り込み登録を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | pmu.c | `sys/powerpc/powermac/pmu.c` | setup_pmu_intr関数（行299-321）で割り込みハンドラをpmu_intrに設定 |
| 3-2 | pmu.c | `sys/powerpc/powermac/pmu.c` | pmu_attach関数（行334-522）でPMU_INT_ENVIRONMENT含む割り込みマスクを設定（行381-382） |

**主要処理フロー**:
- **行72-74**: PMU_DEFAULTSマクロでPMU_INT_ENVIRONMENTを含む割り込みマスクを定義
- **行312-313**: bus_setup_intrでpmu_intrを割り込みハンドラとして登録

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

```
[ハードウェア割り込み]
    |
    +-- pmu_intr(arg)                           [sys/powerpc/powermac/pmu.c:696]
           |
           +-- pmu_send(sc, PMU_INT_ACK, ...)   [sys/powerpc/powermac/pmu.c:596]
           |
           +-- [resp[1] & PMU_INT_ENVIRONMENT チェック]
           |
           +-- [resp[2] & PMU_ENV_LID_CLOSED && !sc->lid_closed チェック]
           |
           +-- devctl_notify("PMU","lid","close",NULL)  [sys/kern/subr_bus.c]
                  |
                  +-- [devctlキューへイベント追加]
                         |
                         +-- [devd(8)が/dev/devctlから読み取り]
```

### データフロー図

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

PMU割り込み信号 ---------> pmu_intr()                ------> devctl_notify()
                           |                                   |
                           +- PMU_INT_ACK応答取得              +- /dev/devctl
                           +- resp[2]のLID_CLOSEDビット確認        |
                           +- sc->lid_closed状態管理              +- devd(8)
                                                                   |
                                                                   +- /etc/devd.conf
                                                                      に基づくアクション
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| pmu.c | `sys/powerpc/powermac/pmu.c` | ソース | PMUドライバ本体。割り込みハンドラpmu_intrでlid close通知を発行 |
| pmuvar.h | `sys/powerpc/powermac/pmuvar.h` | ヘッダ | PMU関連の定数定義（PMU_ENV_LID_CLOSED等）とpmu_softc構造体定義 |
| viareg.h | `sys/powerpc/powermac/viareg.h` | ヘッダ | VIAレジスタ定義（割り込みフラグレジスタvIFR等） |
| subr_bus.c | `sys/kern/subr_bus.c` | ソース | devctl_notify関数の実装 |
