/**//* name: pci.c */ #include <stdio.h> #include <assert.h> #include <sys/io.h> #define IO_PORTS1 1 /* ioport <= 0x3ff */ #define IO_PORTS2 2 /* ioport >0x3ff && ioport < 0xffff */ #define IO_PERMOFF 0 #define IO_PERMON 1 #define IO_PERMON2 3 #define RW_DELAY 10000 /*delay 100000 microseconds for reading and writing I/O ports. */ #ifndef BOOL typedef unsigned char BOOL; #endif #ifndef BYTE typedef unsigned char BYTE; #endif #ifndef DWORD typedef unsigned long DWORD; #endif #ifndef INT typedef unsigned int INT; #endif #ifndef ULONG typedef unsigned long ULONG; #endif #ifndef WORD typedef unsigned short WORD; #endif /**//* ** Function : Write the value of the specified I/O port by giving the length and the ** starting address. ** Parameter: PortAddr: the port address ** PortVal : the value to set ** size : size = 1 for reading 1 byte, 2 for word, 4 for double words ** Return : 1 returned if success, or 0 returned */ BOOL SetPortVal(WORD PortAddr, DWORD PortVal, BYTE size) ...{ BOOL Ret =0; INT tmpRet =0; ULONG numperm =1; INT privilege =0; assert(PortAddr>0); if(PortAddr <=0x3ff) ...{ tmpRet = ioperm((ULONG)PortAddr, numperm, IO_PERMON); privilege = IO_PORTS1; } elseif( PortAddr >0x3ff) ...{ tmpRet = iopl(IO_PERMON2); privilege = IO_PORTS2; } else return Ret; if(tmpRet<0) ...{ fprintf(stderr, "can't set the io port permission for setting ! "); return Ret; } else ...{ switch(size) ...{ case1: /**//*write one byte to the port */ outb(PortVal, PortAddr); break; case2: /**//*write one word to the port */ outw(PortVal, PortAddr); break; case4: /**//*write double words to the port */ outl(PortVal, PortAddr); break; default: Ret =0; break; } usleep(RW_DELAY); Ret =1; } if( privilege == IO_PORTS1 ) ioperm((ULONG)PortAddr, numperm, IO_PERMOFF); elseif(privilege == IO_PORTS2 ) iopl(IO_PERMOFF); return Ret; } /**//* ** Function : Read the value of the specified I/O port by giving the lenght and the ** starting address. ** Parameter: PortAddr : the port address ** PortVal : value from port ** size : size = 1 for reading 1 byte, 2 for word, 4 for double words ** Return : 1 returned if success, or 0 returned. */ BOOL GetPortVal(WORD PortAddr, DWORD * PortVal, BYTE size) ...{ BOOL Ret =0; int tmpRet =0; unsigned long numperm =1; int privilege =0; assert(PortAddr>0); assert(PortVal!=NULL); if(PortAddr <=0x3ff) ...{ tmpRet = ioperm((unsigned long)PortAddr, numperm, IO_PERMON); privilege = IO_PORTS1; } elseif( PortAddr >0x3ff) ...{ tmpRet = iopl(IO_PERMON2); privilege = IO_PORTS2; } else return Ret; if(tmpRet<0) ...{ fprintf(stderr, "can't set the io port permission for reading ! "); return Ret; } else ...{ switch(size) ...{ case1: /**//*read one byte from the port */ *PortVal = inb(PortAddr); break; case2: /**//*read one word from the port */ *PortVal = inw(PortAddr); break; case4: /**//*read double words from the port */ *PortVal = inl(PortAddr); break; default: Ret =0; break; } usleep(RW_DELAY); Ret =1; } if( privilege == IO_PORTS1 ) ioperm( (unsigned long)PortAddr, numperm, IO_PERMOFF ); elseif( privilege == IO_PORTS2 ) iopl(IO_PERMOFF); return Ret; } int main (int argc, char* argv[]) ...{ WORD add_port =0xcf8; WORD data_port =0xcfc; DWORD addr =0x80000000; DWORD port_value; BYTE size =4; int input; printf("Please select the option number as follow: "); printf("1--bus 0:dev:0 fun:0 as address 0x80000000 "); printf("2--bus 0:dev:1 fun:0 as address 0x80000800 "); printf("3--input your own defined address value: "); scanf("%d",&input); switch(input) ...{ case1: addr=0x80000000; break; case2: addr=0x80000800; break; case3: printf("please input the 32 bits address in Hex format(such as 80007800): "); scanf ("%x", &addr); break; default: printf("input invalid option num, exit program. "); return-1; } printf ("The addr is :%X ", addr); printf ("The add_port is : %X ", add_port); printf ("The data_port is : %X ", data_port); if (SetPortVal(add_port, addr, size)) ...{ if (GetPortVal(data_port, &port_value, size)) ...{ printf("port value is :%08X ", port_value); return0; } } return-1; }