AR# 38389

12.3 EDK - 割り込みが原因でペリフェラルに複数アクセスが発生し、PowerPC 440 デザインのデータが破損

説明


PowerPC 440 システムで、1 つのペリフェラル ロケーションにアクセスがあるとき、アクセス中に割り込みがあると、アクセスが 2 回発生します。ペリフェラル FIFO ロケーションやステータス レジスタなど、1 つのトランザクションに対し読み出しまたは書き込みを 1 回しか実行できないロケーションにアクセスがあるとき、エラーが発生します。

この動作の原因と回避策を教えてください。

ソリューション

特定値に 1 度しかアクセスできないメモリ ロケーションはすべて TLB の保護されているアドレス範囲の一部である必要があります。詳細は、ppc440x5_um.pdf ファイルの 141 ページを参照してください。
5.6.4 Guarded (G)

保護されているストレージ属性は、誤動作が起きているメモリ ロケーションへの不正アクセスを制御するためのものです。
対応する実ストレージが存在し、それにエラーがない場合、また、そのストレージへの 1 回のアクセスが複数の同じアクセスと実質違わない場合、ストレージの動作には「問題がない」とみなされます。その場合、データおよび命令は、他に問題を引き起こすことなく、動作に問題のないストレージから順不同でフェッチされます。

一般的に、誤動作のないストレージは guarded と記されているはずです。ストレージは I/O デバイス上の制御レジスタであったり、存在しないロケーションがストレージに含まれていたりする可能性があるので、順不同アクセスがストレージにあると、I/O デバイスの操作が予期しないものであったり、またはマシン チェック例外が発生することがあります。たとえば、シリアル I/O デバイスの入力バッファーがメモリ マップされている場合、そのロケーションへに順不同アクセスや不正アクセスがあると、命令実行に割り込みがあったり、再試行された場合、入力バッファからのデータが損失したりする可能性があります。


回避策 :


複数アクセスが認められない I/O ペリフェラル範囲にあるすべての TLB エントリに対し保護ビットを設定します。たとえば、0x8000000 から 0x9FFFFFFF までの I/O 範囲を設定する場合は、次のコードを使用します。

#include "xtlb_l.h"

/* Initialize peripherals as guarded */
{
unsigned short page;
int attrib;
int ts; /* Translation Space */

for (ts=0;ts<=1;ts++){

/* 0x8000_0000 to 0x8FFF_FFFF */
page = XTlb_FindPage(0x80000000, 0x0, ts);
attrib = XTlb_GetStorAttribAccessCtrl(page);
XTlb_SetStorAttribAccessCtrl(page, ((short) attrib) | ( 1 << 8 ));

/* 0x9000_0000 to 0x9FFF_FFFF */
page = XTlb_FindPage(0x90000000, 0x0, ts);
attrib = XTlb_GetStorAttribAccessCtrl(page);
XTlb_SetStorAttribAccessCtrl(page, ((short) attrib) | ( 1 << 8 ));
}
}


AR# 38389
日付 12/20/2010
ステータス アクティブ
種類 一般
ツール 詳細 概略
IP