X86主板驱动开发:使用DDK函数读写主板芯片组寄存器出错

iwillbeback008 2011-03-24 04:33:52
使用AMD的最新X86 APU做驱动开发:使用DDK函数读写主板芯片组寄存器出错,请教

安装了XP+SP3,使用200的DDK进行驱动开发,
对于读写I/O映射空间的以下函数
8位输入:UCHAR READ_PORT_UCHAR((PUCHAR)port)
16位输入:USHORT READ_PORT_USHORT((PUSHORT)port)
32位输入:ULONG READ_PORT_ULONG((PULONG)port)

8位输出:WRITE_PORT_UCHAR((PUCHAR)port,(UCHAR)value)
16位输出:WRITE_PORT_USHORT((PUSHORT)port,(USHORT)value)
32位输出:WRITE_PORT_ULONG((PULONG)port,(ULONG)value)
可以正常使用;

对于蜂鸣器可以操作(操作端口0x40h-0x43h和ox61h),可以通过oxCF8h和0xCFC端口读出挂载在内部PCI线上的Configuration Register区域数据。

但是如果我要读写芯片组上的寄存器{对与内存映射的空间的读写},在自己编写的驱动程序中使用READ_REGISTER_ULONG函数,在应用程序上使用DeviceIoControl调用驱动程序的READ_REGISTER_ULONG函数,在DriverMonitor软件中提示:
1853.922 Win32 RTL: RtlNtStatusToDosError(0xc0000232): No Valid Win32 Error Mapping
1853.922 Default Enter HelloDDKDispatchRoutin
1853.922 Win32 RTL: Edit ntos\rtl\generr.c to correct the problem
1853.922 Default IRP_MJ_CREATE
1853.922 Win32 RTL: ERROR_MR_MID_NOT_FOUND is being returned
1853.922 Default Leave HelloDDKDispatchRoutin
1853.922 Win32 RTL: RtlNtStatusToDosError(0xc0000232): No Valid Win32 Error Mapping

1853.922 Default Enter HelloDDKDeviceIOControl
1853.922 Win32 RTL: Edit ntos\rtl\generr.c to correct the problem
1853.922 Default Leave HelloDDKDeviceIOControl
1853.922 Win32 RTL: ERROR_MR_MID_NOT_FOUND is being returned

1853.922 Default Enter HelloDDKDeviceIOControl
1853.922 Default Leave HelloDDKDeviceIOControl
1853.938 Win32 RTL: RtlNtStatusToDosError(0xc0000232): No Valid Win32 Error Mapping

这样的信息,

请教这些对于内存映射的空间的读写的DDK函数,关于函数的参数问题,使用上要注意啥?
最好给出个实际例子
...全文
320 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
iwillbeback008 2011-08-09
  • 打赏
  • 举报
回复
问题找到了,是地址映射出了问题。
可以加我QQ
  • 打赏
  • 举报
回复
楼主 问题后来如何解决的呢 小弟邮箱damoliuyunli@163.com 希望可以把您的经验发给小弟一份 小弟现在遇到同样问题了
m_cmd 2011-04-05
  • 打赏
  • 举报
回复
直接读写IO的方法来获取PCI Config的方法,在XP以上是不被推荐的,主要是在多核cpu上有同步问题,但是一般也不会有什么问题。
如果你只想做IO操作,那么用Winio这个驱动好了,没必要自己写。具体你可以搜索一下winio

iwillbeback008 2011-03-24
  • 打赏
  • 举报
回复
贴上Driver.cpp的HelloDDKDeviceIOControl函数,在对内存映射范围的寄存器读写使用了READ_REGISTER_ULONG和WRITE_REGISTER_ULONG函数:

#pragma PAGEDCODE
NTSTATUS HelloDDKDeviceIOControl(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp)
{
NTSTATUS status = STATUS_SUCCESS;
KdPrint(("Enter HelloDDKDeviceIOControl\n"));

//得到当前堆栈
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);
//得到输入缓冲区大小
ULONG cbin = stack->Parameters.DeviceIoControl.InputBufferLength;
//得到输出缓冲区大小
ULONG cbout = stack->Parameters.DeviceIoControl.OutputBufferLength;
//得到IOCTL码
ULONG code = stack->Parameters.DeviceIoControl.IoControlCode;

ULONG info = 0;

switch (code)
{ // process request
case READ_PORT:
{
KdPrint(("READ_PORT\n"));
//缓冲区方式IOCTL
//显示输入缓冲区数据
PULONG InputBuffer = (PULONG)pIrp->AssociatedIrp.SystemBuffer;
ULONG port = (ULONG)(*InputBuffer);
InputBuffer++;
UCHAR method = (UCHAR)(*InputBuffer);

KdPrint(("port:%x\n",port));
KdPrint(("method:%x\n",method));
//操作输出缓冲区
PULONG OutputBuffer = (PULONG)pIrp->AssociatedIrp.SystemBuffer;

if (method==1)//8位操作
{
*OutputBuffer = READ_PORT_UCHAR((PUCHAR)port);
}
//设置实际操作输出缓冲区长度
info = 4;

break;
}
case WRITE_PORT:
{
KdPrint(("WRITE_PORT\n"));
//缓冲区方式IOCTL
//显示输入缓冲区数据
PULONG InputBuffer = (PULONG)pIrp->AssociatedIrp.SystemBuffer;
ULONG port = (ULONG)(*InputBuffer);
InputBuffer++;
UCHAR method = (UCHAR)(*InputBuffer);
InputBuffer++;
ULONG value = (ULONG)(*InputBuffer);

KdPrint(("port:%x\n",port));
KdPrint(("method:%x\n",method));
KdPrint(("value:%x\n",value));

//操作输出缓冲区
PULONG OutputBuffer = (PULONG)pIrp->AssociatedIrp.SystemBuffer;

if (method==1)//8位操作
{
WRITE_PORT_UCHAR((PUCHAR)port,(UCHAR)value);
}
//设置实际操作输出缓冲区长度
info = 0;
break;
}
//add by Rn 20110324-----------------------
case READ_REG:
{
KdPrint(("READ_REG\n"));
//缓冲区方式IOCTL
//显示输入缓冲区数据
PULONG InputBuffer = (PULONG)pIrp->AssociatedIrp.SystemBuffer;
ULONG reg = (ULONG)(*InputBuffer);
InputBuffer++;
UCHAR method = (UCHAR)(*InputBuffer);

KdPrint(("reg:%x\n",reg));
KdPrint(("method:%x\n",method));
//操作输出缓冲区
PULONG OutputBuffer = (PULONG)pIrp->AssociatedIrp.SystemBuffer;

if(method==4)//32位操作
{
*OutputBuffer = READ_REGISTER_ULONG((PULONG)reg);
}

KdPrint(("Read Data Value: 0X%08X\n",*OutputBuffer));
//设置实际操作输出缓冲区长度
info = 4;

break;
}
case WRITE_REG:
{
KdPrint(("WRITE_REG\n"));
//缓冲区方式IOCTL
//显示输入缓冲区数据
PULONG InputBuffer = (PULONG)pIrp->AssociatedIrp.SystemBuffer;
ULONG reg = (ULONG)(*InputBuffer);
InputBuffer++;
UCHAR method = (UCHAR)(*InputBuffer);
InputBuffer++;
ULONG value = (ULONG)(*InputBuffer);

KdPrint(("reg:%x\n",reg));
KdPrint(("method:%x\n",method));
KdPrint(("value:%x\n",value));

//操作输出缓冲区
PULONG OutputBuffer = (PULONG)pIrp->AssociatedIrp.SystemBuffer;

if(method==4)//32位操作
{
WRITE_REGISTER_ULONG((PULONG)reg,(ULONG)value);
}

//设置实际操作输出缓冲区长度
info = 0;
break;
}
//-----------------------------------------
default:
status = STATUS_INVALID_VARIANT;
}

// 完成IRP
pIrp->IoStatus.Status = status;
pIrp->IoStatus.Information = info; // bytes xfered
IoCompleteRequest( pIrp, IO_NO_INCREMENT );

KdPrint(("Leave HelloDDKDeviceIOControl\n"));

return status;
}
iwillbeback008 2011-03-24
  • 打赏
  • 举报
回复
贴上main.c:

#include <windows.h>
#include <stdio.h>
//使用CTL_CODE必须加入winioctl.h
#include <winioctl.h>
#include "..\NT_Driver\Ioctls.h"

//add by Rn 20110321
/* APU Power Management (PM) Registers */
#define PM_INDEX_ADDRESS 0xCD6
#define PM_DATA 0xCD7

UCHAR In_8(HANDLE hDevice,ULONG/*USHORT*/ port)
{
DWORD dwOutput ;
DWORD inputBuffer[2] =
{
port,//对port进行操作
1//1代表8位操作,2代表16位操作,4代表32位操作
};
DWORD dResult;

DeviceIoControl(hDevice, READ_PORT, inputBuffer, sizeof(inputBuffer), &dResult, sizeof(DWORD), &dwOutput, NULL);

return (UCHAR) dResult;

}

void Out_8(HANDLE hDevice,ULONG/*USHORT*/ port,UCHAR value)
{
DWORD dwOutput ;
DWORD inputBuffer[3] =
{
port,//对port进行操作
1,//1代表8位操作,2代表16位操作,4代表32位操作
value//输出字节
};

DeviceIoControl(hDevice, WRITE_PORT, inputBuffer, sizeof(inputBuffer), NULL, 0, &dwOutput, NULL);
}

DWORD ReadReg_32(HANDLE hDevice,ULONG reg)
{
DWORD dwOutput ;
DWORD inputBuffer[2] =
{
reg,//对register进行操作
4//1代表8位操作,2代表16位操作,4代表32位操作
};
DWORD dResult;

DeviceIoControl(hDevice, READ_REG, inputBuffer, sizeof(inputBuffer), &dResult, sizeof(DWORD), &dwOutput, NULL);

return dResult;

}

void WriteReg_32(HANDLE hDevice,ULONG reg,DWORD value)
{
DWORD dwOutput ;
DWORD inputBuffer[3] =
{
reg,//对register进行操作
4,//1代表8位操作,2代表16位操作,4代表32位操作
value//输出字节
};

DeviceIoControl(hDevice, WRITE_REG, inputBuffer, sizeof(inputBuffer), NULL, 0, &dwOutput, NULL);
}

BOOL SetPCIGPIO(HANDLE hDevice/*,UCHAR offset*/)
{
//DWORD dwAddr;
int i;
UCHAR offset;
UCHAR ucData;

DWORD AcpiMMioAddr;
DWORD dwData;

//---------------------------------------------------------
//test IO-Mapped Control Registers:0xCD6/0xCD7
printf("test IO-Mapped Control Registers--0xCD6/0xCD7:\n");

offset = 0x20; //0x00; //IsaDecode - RW – 8/16/32 bits - [PM_Reg: 00h]
dwData = 0x00000000;

for (i = 0; i < 4; i ++)
{
Out_8(hDevice,PM_INDEX_ADDRESS, offset+i);
ucData = In_8(hDevice,PM_DATA);
// printf("[MISC_Reg: 0X%02Xh]\tDefault data:0X%02X\n",offset+i,ucData);
dwData += (ucData<<(i*8));
}
printf("[MISC_Reg: 0X%02Xh]\tdata:0X%08X\n\n",offset,dwData);
/*
//错误的读法:使用32位的方法读写8位端口
offset = 0x24;
Out_8(hDevice,PM_INDEX_ADDRESS, offset);
dwData = In_32(hDevice,PM_DATA);
printf("[MISC_Reg: 0X%02Xh]\tdata:0X%08X\n",offset,dwData);
*/
//---------------------------------------------------------------
/* Read PM Registers */
printf("Read PM Registers:\n");

offset = 0x24; //AcpiMmioEn - RW – 8/16/32 bits - [PM_Reg: 24h]
dwData = 0x00000000;
for (i = 0; i < 4; i ++)
{
Out_8(hDevice,PM_INDEX_ADDRESS, offset+i);
ucData = In_8(hDevice,PM_DATA);
// printf("[MISC_Reg: 0X%02Xh]\tDefault data:0X%02X\n",offset+i,ucData);
dwData += (ucData<<(i*8));
}
printf("[PM_Reg: 0X%02Xh]\tdata:0X%08X\n",offset,dwData);

//--------------------------------
/* Set PM Registers */
offset = 0x24; //AcpiMmioEn - RW – 8/16/32 bits - [PM_Reg: 24h]
dwData = 0x00000000;
AcpiMMioAddr = 0xFED80000;

Out_8(hDevice,PM_INDEX_ADDRESS, offset);
Out_8(hDevice,PM_DATA, 0X01); //enable AcpiMMio space,Memory-mapped space;
Out_8(hDevice,PM_INDEX_ADDRESS, offset+1);
Out_8(hDevice,PM_DATA, 0X00);
Out_8(hDevice,PM_INDEX_ADDRESS, offset+2);
Out_8(hDevice,PM_DATA, 0XD8);
Out_8(hDevice,PM_INDEX_ADDRESS, offset+3);
Out_8(hDevice,PM_DATA, 0XFE);

/* Test Set PM Registers */
for (i = 0; i < 4; i ++)
{
Out_8(hDevice,PM_INDEX_ADDRESS, offset+i);
ucData = In_8(hDevice,PM_DATA);
dwData += (ucData<<(i*8));
}
printf("[PM_Reg: 0X%02Xh]\tdata:0X%08X\n",offset,dwData);
//--------------------------------
/* Set PcibConfig Registers */
offset = 0xEA; //PcibConfig - RW – 8 bits - [PM_Reg: EAh]
Out_8(hDevice,PM_INDEX_ADDRESS, offset);
ucData = In_8(hDevice,PM_DATA);
printf("Set PcibConfig Registers before,[PM_Reg: 0X%02Xh]\tdata:0X%02X\n",offset,ucData);
Out_8(hDevice,PM_DATA, 0x01); //enable PCI interface pins to function as GPIO {GPIO 35:0}
//Out_8(hDevice,PM_DATA, 0x00); //PCI AD[31:0]

ucData = In_8(hDevice,PM_DATA);
printf("Set PcibConfig Registers after,[PM_Reg: 0X%02Xh]\tdata:0X%02X\n\n",offset,ucData);

//--------------------------------
/* Set IoMux Registers
IoMux<N>-Gpio<X> – R/W 8 bits - [IoMux_Reg: <N>h]
“AcpiMMioAddr” + 0xD00 to “AcpiMMioAddr” + 0xDFF
*/
WriteReg_32(hDevice,AcpiMMioAddr+0xD007,0x01); //set PCI-AD[7] to GPIO[7];

/* Set GPIO Registers Registers
Gpio<N> – R/W 8 bits - [Gpio_Reg: NNh]
“AcpiMMioAddr” + 0x100 to “AcpiMMioAddr” + 0x1FF
*/
WriteReg_32(hDevice,AcpiMMioAddr+0x1007,0x01); //GPIO[7] Set Up;
//---------------------------------------------------------

return 1;
}

int main()
{
HANDLE hDevice =
CreateFile("\\\\.\\HelloDDK",
GENERIC_READ | GENERIC_WRITE,
0, // share mode none
NULL, // no security
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL ); // no template

if (hDevice == INVALID_HANDLE_VALUE)
{
printf("Failed to obtain file handle to device: "
"%s with Win32 error code: %d\n",
"MyWDMDevice", GetLastError() );
return 1;
}

//DisplayPCIConfiguation(hDevice,2,1,0); //note by Rn 20110321
SetPCIGPIO(hDevice/*,0x24*/); //add by Rn 20110321

CloseHandle(hDevice);

return 0;
}

21,595

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 驱动开发/核心开发
社区管理员
  • 驱动开发/核心开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧