0

我有一个关于如何基于WinIo v3.0中的SetPhysLong()为1Byte/2Byte访问构建例程的问题。

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. 假设该寄存器的第二个字节是状态寄存器,属性是“写 1 清除”,第二个字节现在是 0x40
  3. 假设我们要将 0xA5 写入内存 0x12345678。按照你的方式,我们得到:

    • 使用 GetPhysLong 然后返回 0x00004000
    • 把 0xA5 放到 LSB,我们得到 0x000040A5
    • 使用 SetPhysLong 将 0x000040A5 设置为内存地址 0x12345678

这是正确的,因为值 0x40 将被写入第二个字节并将其清除为 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

请参阅此问题的 [EDIT] 部分!

于 2012-11-27T03:05:23.670 回答