0

WinIo v3.0でSetPhysLong()に基づいて1Byte/2Byteアクセスのルーチンを構築する方法について 1 つ質問があります。

SetPhysLong()は、DWORD(32bit) 単位でメモリにアクセスするために使用され、私の目的は、独自のルーチンを構築することです。

  • SetPhysBYTE()でBYTE(8bit unsigned)単位でメモリアクセスし、
  • SetPhysWORD()でWORD(16bit unsigned)単位でメモリアクセス

誰かがこの問題を解決できる方法を以下に教えてくれました:

  1. GetPhysLongを使用して、現在の DWORD コンテンツを取得します
  2. 新しいBYTE / WORDをDWORDの正しい部分に入れます
  3. 次にSetPhysLongを使用してそれを書き戻します

しかし、以下の状況が発生した場合、上記の方法は失敗したと思います:

  1. 4 バイトのレジスタがメモリ 0x12345678 にマップされていると仮定します (これはメモリにマップされた IO であるため)。
  2. そのレジスタの 2 番目のバイトがステータス レジスタであり、属性が「Write 1 to clear」であり、2 番目のバイトが 0x40であると仮定します。
  3. 0xA5 をメモリ 0x12345678 に書き込みたいとします。あなたのやり方に従ってください、私たちは得ました:

    • GetPhysLong を使用し、0x00004000 を返します
    • LSBに0xA5を入れると、0x000040A5が得られました
    • SetPhysLong を使用して、0x000040A5 をメモリ アドレス 0x12345678 に設定します。

値 0x40 が 2 番目のバイトに書き込まれ、0x00 にクリアされるため、これは正しくありません!!!

したがって、私の目的は SetPhysBYTE(0x12345678, 0xA5) を使用して目標を達成し、以下の SetPhysLong() に基づいて他のバイトに影響を与えないようにすることです...

bool _stdcall SetPhysLong(PBYTE pbPhysAddr, DWORD dwPhysVal)
{
    PDWORD pdwLinAddr;
    tagPhysStruct PhysStruct;

    if (!IsWinIoInitialized)
        return false;

    if (g_Is64BitOS)
    {
        PhysStruct.pvPhysAddress = (DWORD64)pbPhysAddr;
    }
    else
    {
        // Avoid sign extension issues
        PhysStruct.pvPhysAddress = (DWORD64)(DWORD32)pbPhysAddr;
    }

    PhysStruct.dwPhysMemSizeInBytes = 4;

    pdwLinAddr = (PDWORD)MapPhysToLin(PhysStruct);

    if (pdwLinAddr == NULL)
        return false;

    *pdwLinAddr = dwPhysVal;

    UnmapPhysicalMemory(PhysStruct);

    return true;
}

[編集] 私はこれを解決しました。必要に応じて以下のコードを参照してください...

bool _stdcall SetPhysBYTE(PBYTE pbPhysAddr, BYTE bPhysVal)
{
PDWORD pdwLinAddr;
tagPhysStruct PhysStruct;

if (!IsWinIoInitialized)
    return false;

if (g_Is64BitOS)
{
    PhysStruct.pvPhysAddress = (DWORD64)pbPhysAddr;
}
else
{
    // Avoid sign extension issues
    PhysStruct.pvPhysAddress = (DWORD64)(DWORD32)pbPhysAddr;
}

PhysStruct.dwPhysMemSizeInBytes = 1;

pdwLinAddr = (PDWORD)MapPhysToLin(PhysStruct);

if (pdwLinAddr == NULL)
    return false;

*(((PBYTE)((DWORD)pdwLinAddr))) = bPhysVal;

UnmapPhysicalMemory(PhysStruct);

return true;
}

bool _stdcall SetPhysWORD(PBYTE pbPhysAddr, WORD wPhysVal)
{
PDWORD pdwLinAddr;
tagPhysStruct PhysStruct;

if (!IsWinIoInitialized)
    return false;

if (g_Is64BitOS)
{
    PhysStruct.pvPhysAddress = (DWORD64)pbPhysAddr;
}
else
{
    // Avoid sign extension issues
    PhysStruct.pvPhysAddress = (DWORD64)(DWORD32)pbPhysAddr;
}

PhysStruct.dwPhysMemSizeInBytes = 2;

pdwLinAddr = (PDWORD)MapPhysToLin(PhysStruct);

if (pdwLinAddr == NULL)
    return false;

*(((PWORD)((DWORD)pdwLinAddr))) = wPhysVal;

UnmapPhysicalMemory(PhysStruct);

return true;
}
4

1 に答える 1

0

この質問の [編集] 部分を参照してください。

于 2012-11-27T03:05:23.670 に答える