21,595
社区成员
发帖
与我相关
我的任务
分享
#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;
}
#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;
}