P/ECE研究室〜S1C33分室



* Wed Jul 12 19:00:00 JST 2002 Naoyuki Sawa




前回に引き続き、フラッシュメモリの話題です。今回は「ソフトウェアIDモード」を使ってみます。




まずは「ソフトウェアIDモード」です。 SST39VF400Aのデータシートによると、ソフトウェアIDモードとは、 フラッシュメモリの製造者や製品情報を取得する ためのモードのことです。(製品識別モードとも呼ばれるようです) ソフトウェアIDモードから取得できる情報は非常に単純で、SST39VF400Aの場合は次のような情報が取得できます。 製造者: SST 製 品: SST39LF400AまたはSST39VF400A 前回の最後に紹介したサンプルプログラムの実行結果を、もう一度示します。
ソースはこちら SST39VF400Aは16ビット×256K構成ですので、フラッシュメモリ全体を次のような配列と見なすことができます。 unsigned short FMEM[256 * 1024]; /* 2バイト×256K = 512Kバイト */ この配列を使って説明すると、ソフトウェアIDモードに入る手順は次のようになります。 FMEM[0x5555] に 0x00aa を書き込む FMEM[0x2aaa] に 0x0055 を書き込む FMEM[0x5555] に 0x0090 を書き込む 普通のモードではフラッシュメモリの書き換えはできませんので、これらの書き換えは一見無意味に見えますが、 フラッシュメモリに対する“隠しコマンド”のような指示となり、ソフトウェアIDモードに切り替わるのです。 (まるで、タイトル画面で一見無意味なボタン操作を行うと、裏ステージモードに切り替わるかのような感覚です) ソフトウェアIDモードに入ると、フラッシュメモリの特定のアドレスから「製造者」と「製品」情報を読み出せます。 FMEM[0x0000] を読み込む … 製造者情報 FMEM[0x0001] を読み込む … 製品情報 これらの情報は単なる番号ですので、あらかじめ番号と製造者・製品の対応を知っていなければ、使いみちがありません。 製造者番号については、JEDECという機関が各製造者ごとに重複しない番号を割り振っているのだそうですが、 残念ながら、どこにその一覧表があるのか、見つけられませんでした。 とりえあずサンプルプログラムでは、製造者がSSTか否か?と、SST39VF400Aや姉妹製品との識別だけを行っています。
さて、製造者と製品に関する情報が取得できたら、すぐにソフトウェアIDモードを抜けなければいけません。 ソフトウェアIDモードを抜ける手順は次のとおりです。 FMEM[0x5555] に 0x00aa を書き込む FMEM[0x2aaa] に 0x0055 を書き込む FMEM[0x5555] に 0x00f0 を書き込む これを忘れるとちょっとマズイことになります。 ソフトウェアIDモードでは、製造者・製品情報以外のメモリ領域へのアクセスは、全て無効になります。 実験したところ、FMEM[0x0000]とFMEM[0x0001]以外のアドレスからの読み出しは、0xffffになりました。 (厳密には、他にもちょっとだけ0xffff以外の値を返すアドレスもあるのですが…CFIクエリーモードの説明時に補足します) もしもソフトウェアIDモードに入ったままプログラムの実行を継続してしまうと、 フラッシュメモリ上のプログラムに処理が移ったとたんに、予測できない結果になります。 システムプログラムを実行するつもりが、その位置には0xffff(無効な命令)しかないのですから。 CPUが無効な命令を検出して、TRAPを発生させたとしても、TRAP処理ルーチンはまたしても0xffff。 TRAPエラー画面を表示することもできず、P/ECEは完全に凍りついてしまいます。
僕も実際に、これをやってしまいましいた。 仕方がないので、背面のリセットボタンを押して復旧させましょう・・・ところが! リセットボタンを押してもP/ECEは凍ったままです SST39VF400Aにはリセット機能がないので、背面のリセットボタンを押してもSST39VF400Aには効果がありません。 つまり、リセットボタンを押してもSST39VF400AはソフトウェアIDモードのままなのです。 リセットボタンを押すと、CPUは0xc00000番地(=フラッシュメモリの先頭アドレス)に書かれたアドレスから実行を開始します。 本来0xc00000番地には、初期化プログラムのアドレスが入っているのですが、ソフトウェアIDモードなので製造者・製品番号が読み出されます。 これでは、正しい初期化プログラムを実行開始できません。 最後の手段。 いったん電池(とUSBケーブル)を抜いて電池を入れ直し、完全な電源再投入なら復旧するでしょう・・・ところが! 電池入れなおしてもP/ECEは凍ったままです もしかして、むちゃくちゃな命令が実行された結果、ホントにフラッシュメモリが壊れてしまったのでしょうか? 電源を再投入しても症状が消えない、という現象。過去にも一度、別の機械で、似たような体験をしたことがあります。 現P/ECEユーザーには元MSXユーザーが多いようなので、覚えておられるかたも多いかと思います。「M-FAN風邪」 詳細は省きますが、電源を切ってもメモリ内容が数分間消えないことを利用して、ROMを装ったプログラムをRAM上に残しておき、 何度パソコンの電源を再投入しても、予期しないプログラムが起動してしまう、といういたずらプログラムでした。 これのすごいところは、大手出版社(徳間書店)が雑誌の付録ディスクで「わざと」やった、という点です。 今やったらすごい非難を浴びるでしょうが、おおらかな時代だったということでしょうか。 M-FAN風邪を直すには、パソコンの電源を切って、10分くらい放っておきます。 すると、いたずらプログラムがRAM上から完全に消えて、元通りのMSX-BASICが起動するようになります。 あせって電源をばちばち入り切りすると、そのたびにいたずらプログラムの内容が復活してしまうので、逆効果です。 このとき僕は学習しました。「パソコンやゲーム機がおかしくなったら、コンセント抜いて一晩寝かせろ」 この教訓、後日、DOS/Vパソコンやドリームキャストでも役に立つことになるのですが、それはまた別の話。 今回も似たようなケースかも知れません。P/ECEの電池を抜いて、しばらく置いてみることにしましょう・・・再び電池セット。 治りました! 推測するに、フラッシュメモリは電源供給がなくなっても、しばらくのあいだ現在のモードを忘れないのだと思います。 先ほどの場合、電池入れ直しの間隔が短かったので、フラッシュメモリがソフトウェアIDモードのままだったのでしょう。 実験したところ、電池を外して15秒くらいで、フラッシュメモリがモードを忘れてくれるようです。10秒ではダメでした。
ソフトウェアIDモードでは、ほとんどのアドレスからの読み出しが0xffffになってしまうので、 ソフトウェアIDモードに入っている間は、絶対にフラッシュメモリ上のプログラムに制御が移らないようにしなければいけません。 説明の順序が逆になりましたが、ソフトウェアIDモードに入る前に、次のような準備が必要です。 まず、割り込みを禁止して、システムプロウグラム内の割り込みルーチンが呼ばれないようにすること。 NMI(マスクできない割り込み)の抑制も忘れてはいけません。 PSRレジスタで割り込み禁止しただけでは、NMIが発生してしまいます。 P/ECEは、システムタイマ(pceTimerGetCount()で返される値です)のカウントアップにNMIを使っているので、これを停止します。 あと、APIを呼び出すのもダメです。 APIのプログラムはフラッシュメモリ上にあるので、0xffffになってしまっています。 ソフトウェアIDモード中にAPIを使う必要なんてなさそうですが、僕はフラッシュメモリ操作のウェイトタイミングを計るために うっかりpceTimerGetPrecisionCount()を使ってしまい、前述の惨状となりました(^^; 割り込み禁止やNMI禁止手順については、カーネルソース(C:\usr\PIECE\sysdev\pcekn\fmacc.c)やサンプルプログラムを参照してください。
ちょっと長くなってしまったので、「CFIクエリーモード」については次回です。 先に、サンプルプログラムの実行結果画面だけ、ご覧下さい。
ソースはこちら (…続きます)

nsawa@piece-me.org