Skip to content

Instantly share code, notes, and snippets.

@tenpoku1000
Last active April 19, 2024 16:00
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tenpoku1000/13fb7dc7e5bd3445c0573b0e286fd3c0 to your computer and use it in GitHub Desktop.
Save tenpoku1000/13fb7dc7e5bd3445c0573b0e286fd3c0 to your computer and use it in GitHub Desktop.
NMI に割り込まれたい

NMI に割り込まれたい

2024/04/20 更新

この記事は、自作OS Advent Calendar 2018の 12/11 の記事として書かれました。

2018 年 12 月現在の PC では NMI が、どんな時に発生するのか、あるいは意図的に発生させることができるのか、調べてみました。 致命的なハードウェア・エラー発生時以外に、デバッグ用途で意図的に発生させることができる場合があるようです。

調べただけで、実機を使って検証などしていませんので、この記事を参照して生じた、いかなる損失・損害について一切の責任を負いません。ご理解をお願いいたします。

IBM PC/AT などの、かつての PC の NMI の仕様

参照した資料は、以下の通りです。

  • トランジスタ技術Special (No.10) 特集 IBM PC & 80286 のすべて
    トランジスタ技術special編集部
    CQ出版 1990/02 初版 第3刷

  • パソコンのレガシィI/O活用大全―割り込みとDMAからシリアル/パラレル・ポート、
    FDD/IDEインターフェースまで (ハードウェアデザインシリーズ)
    桑野 雅彦
    CQ出版 2000/10 初版 第1刷

  • bochs.sourceforge.net/techspec/PORTS.LST
    https://bochs.sourceforge.io/techspec/PORTS.LST

NMI(Non-Maskable Interrupt:マスク不可能割り込み)という呼称であっても、I/O ポートでマスク(無効化)できるように設計されています。

I/O ポート 61H: システム・ポート(PORT B)

  read bit 7(MPE)      メモリ・パリティ・エラー検出時に 1
  read bit 6(IOCE)     I/O チャネル・エラー検出時に 1
 write bit 3(ENAIOCHK) 1: I/O チャネル・エラー(ISA Bus の IOCHK 信号)による NMI 発生許可
  read bit 3(ENAIOCHK) I/O チャネル・エラー設定値の読み出し
 write bit 2(ENAMPEC)  1: メモリ・パリティ・エラーによる NMI 発生許可
  read bit 2(ENAMPEC)  メモリ・パリティ・エラー設定値の読み出し

I/O ポート 70H: NMI マスク/RTC レジスタ指定(下位 7 ビットが RTC アドレス指定になっている)

 write bit 7(NMI_EN)   0: すべての NMI 発生源を許可しない
  read bit 7(NMI_EN)   すべての NMI 発生源の許可状態の読み出し

2018 年 12 月現在の PC の NMI の仕様

参照した資料は、以下の通りです。Intel® 300 Series Chipset は、Coffee Lake/Coffee Lake Refresh 向けチップセットです。

資料 1 の 28.1.2 NMI Enable (and Real Time Clock Index) (NMI_EN)— Offset 70h によると、I/O ポート 70H: NMI マスク/RTC レジスタ指定の仕様は、特に変更点はないようです。

資料 1 の 28.1.1 NMI Status and Control (NMI_STS_CNT)—Offset 61h によると、I/O ポート 61H: システム・ポート(PORT B)の NMI 発生源が変更になっています。

I/O ポート 61H: システム・ポート(PORT B)

  read bit 7(SERR_NMI_STS)  PCI SERR# 状態の読み出し
  read bit 6(IOCHK_NMI_STS) LPC SERIRQ 状態の読み出し
 write bit 3(IOCHK_NMI_EN)  1: LPC SERIRQ による NMI 発生許可
  read bit 3(IOCHK_NMI_EN)  LPC SERIRQ による NMI 設定値の読み出し
 write bit 2(PCI_SERR_EN)   1: PCI SERR# による NMI 発生許可
  read bit 2(PCI_SERR_EN)   PCI SERR# による NMI 設定値の読み出し

PCI SERR# とは何か(レガシー PC での、メモリ・パリティ・エラーによる NMI 発生が仕様変更)

参照した資料は、以下の通りです。

PCI のコマンド・レジスタ(Offset 4h)における SERR# は、以下の通りです。

bit 8 - 1: SERR#(PCI 上で発生した致命的なエラー) 発生許可
bit 6 - 1: Parity Error Response Enable(bit 8 が 1 の場合、アドレス・パリティ・エラー時に SERR# が発生)

PCI Express のコマンド・レジスタ(Offset 4h)における SERR# は、以下の通りです。

bit 8 - 1: SERR#(PCI Express 上で発生した致命的や致命的ではないエラー) 発生許可(ルートコンプレックスに通知される)
bit 6 - 1: Parity Error Response Enable(ステータス・レジスタの bit 8: Master Data Parity Error の有効化)

LPC SERIRQ とは何か(レガシー PC での、ISA Bus の IOCHK 信号による NMI 発生が仕様変更)

資料 2 によると、SERIRQ はシリアル化された Intel 8259 互換割り込み信号であるようです。すべての LPC デバイスが単一の割り込み線を共有します。 LPC(Low Pin Count)とは、チップセットと BIOS や Super I/O(レガシーデバイスを集積したチップ)を繋ぐための、ISA Bus の後継 Bus です。 チップセットには、LPC Bridge が用意されていて、PCI デバイスとしてアクセス可能になっているようです。

資料 3: 3.3 IRQ/Data Frame によると、LPC SERIRQ における ISA Bus の IOCHCK# 相当の割り込みは、17 番目に定義されているようです。

IRQSER     Sampling Periods IRQ/Data Frame Signal Sampled # of clocks past Start
 1 IRQ0     2
 2 IRQ1     5
 3 SMI#     8
 4 IRQ3    11
 5 IRQ4    14
 6 IRQ5    17
 7 IRQ6    20
 8 IRQ7    23
 9 IRQ8    26
10 IRQ9    29
11 IRQ10   32
12 IRQ11   35
13 IRQ12   38
14 IRQ13   41
15 IRQ14   44
16 IRQ15   47
17 IOCHCK# 50

資料 1 の 2.1.9 Serial IRQ Control (SCNT)—Offset 64h にて、LPC SERIRQ の制御の方法が書かれているようですが、この記事では省略します。

NMI を意図的に発生させる方法

Windows で、NMI スイッチ押下時にメモリダンプするというデバッグ用の機能があるようで、自作 OS でも参考になる機能だと思います。

カーネルまたは完全なクラッシュ ダンプを生成する - Windows Client | Microsoft Learn
https://learn.microsoft.com/ja-jp/troubleshoot/windows-client/performance/generate-a-kernel-or-complete-crash-dump

NMI スイッチを取付可能なマザーボードを探してみました。ローエンド・サーバ用です。LGA1151 なので、デスクトップ PC 用の Skylake/Kaby Lake が使えます。

ASRock Rack > E3C236D2I
https://www.asrockrack.com/general/productdetail.asp?Model=E3C236D2I#Specifications

サーバ・ラック用ではなく、デスクトップ PC ケースを使う場合は、マザーボードの NMI 内部コネクタをジャンパ線でケース外に引き出して、 ジャンパ線にスイッチを取り付けるようにすれば良さそうな気がします。

Amazon.co.jp: KONDOLEN ブレッドボード?ジャンパーワイヤ(メス-オス)(20cm)40本 1 個 : 産業・研究開発用品
https://www.amazon.co.jp/dp/B00P9BVKOK/?th=1

Amazon | アイネックス 実験用スイッチ・LEDセット KM-01 | アイネックス(AINEX) | パソコン用ネジ 通販
https://www.amazon.co.jp/dp/B000FHQADO/?th=1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment