unable to read pci config address(0xcfc) data;

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
nuralam89
Posts: 5
Joined: Mon Feb 09, 2015 4:53 am

unable to read pci config address(0xcfc) data;

Post by nuralam89 »

i have written to 0xcf8. After that tried to access (read) pci configuration space from location 0xcfc and got a garbage value. Please give me any suggestion or direction in this regard.

The code i have used.......(as follows):


#include<stdio.h>
#include<stdlib.h>
#include<linux/pci.h>
#include<sys/io.h>
#include<kernel/pci.h>

#define INDEX_PCI 0xCF8
#define DATA_PCI 0xCFC

long __read_PCI_config (long _devvid, int _offset); //Function prototype

void main (void)
{
unsigned int i;
printf("\n in main \n ");
printf("DVID: 0x20811022 offset 0x10 = 0x%08x",__read_PCI_config(0x3a30, 0x10));
printf("\n i= %d \n",i);
i=pci_read_word(0xCFC,0);
printf("\n i= %d\n",i);
}

long __read_PCI_config (long _devvid, int _offset)
// This function will return the data from the supplied offset into the PCI configuration
// space of the first device found that matches the supplied Device and Vendor ID or zero
// if no match is found.
{
long scankey;
int bus, device, function,i;

printf("\n in read pci");
fflush(stdout);
i=ioperm(3320,32,1);

printf("\n value of ioperm ret =%d",i);

//Search each bus, device, function...
for(bus = 0; bus < 256; bus++)
{
for(device = 0; device < 32; device++)
{
for(function = 0;function < 8; function++)
{
outl((8 << 28 | bus << 16 | device << 11 | function << 8 ),INDEX_PCI);
i=ioperm(3324,64,1);
scankey = inl(DATA_PCI);
//printf("\n scan key = %d ",scankey);
if (scankey == _devvid)
{
printf("\n in 2nd if");
outl(( (8 << 28 | bus << 16 | device << 11 | function << 8 ) + _offset),INDEX_PCI);
return inl_p( DATA_PCI );
}
}

}
}
printf("\n ioperm for CFC =%d",i);
printf("\n scan key= %u",scankey);


//No Match
return 0L;
}
johnsa
Member
Member
Posts: 296
Joined: Mon Oct 15, 2007 3:04 pm

Re: unable to read pci config address(0xcfc) data;

Post by johnsa »

Firstly, I wouldn't suggest scanning the whole pci tree to find a vendor/device id each time..

I would have a read_pci function which takes (bus,device,function,ofs) and just reads that.
You'd enumerate the bus and store the relevant mapping so you know exactly which bus/dev/func corresponds to which device you want to read/write.

I'm not sure about this line:
printf("DVID: 0x20811022 offset 0x10 = 0x%08x",__read_PCI_config(0x3a30, 0x10));

you're passing in a long (assuming this is compiling as a dword(32bit))
that is support to contain both the vendor and device id .. 0x3a30 is a short so some part is implied to be 0000?
Hence why my above suggest about the function with separate parameters would make it easier to use and verify (as you can also ensure that each parameter is withing range including function (<0x3f) and ofs etc.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: unable to read pci config address(0xcfc) data;

Post by Combuster »

nuralam89 wrote:#include<linux/pci.h>
Why are you picking a fight with the linux kernel and not using lspci?
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
nuralam89
Posts: 5
Joined: Mon Feb 09, 2015 4:53 am

how does pci device information is mapped or initialize.....

Post by nuralam89 »

Hi,


Is the Configuration Mechanism described in the PCI spec for software

implementation(ie OS implementation). actually i am trying to

implement a tiny bootable piece of code(a kind of small Operating

system) through which(by writing code) i want to access data from hard

disk.


i have tried a bit to write pci CONFIG_ADDRESS and read data from config_DATA.

but it returned 0 each time( I gave different Device _ID from 'lspci' info) .

I have few queries in this regard.

1.Does pci bus and device needs insitalization(i mean to map specific bus and device) if so than how it works(is their any protocol??)??

2.if i try to access the CONFIG_ADDRESS & CONFIG_DATA in my piece of bootable code(where i just wrote a piece of nasm assembly code & linker to boot; printing a string on VGA-memory part after booting and it will hang there.i have not done any kind of mapping or initilization) what information it should provide??

3. in "pci.h" struct pci_dev{...} who initializes or maps the sub field of this struct data type.

4.specifically how does kernel initialize different device to different bus number so that we can access information about the device by reading CONFIG_ADDRESS & CONFIG_DATA by different predefined offset value(i.e. 0x0e for HEADER).
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: unable to read pci config address(0xcfc) data;

Post by Combuster »

but it returned 0 each time( I gave different Device _ID from 'lspci' info) .
Assuming you ran your bootloader on the same machine as where you ran lspci, and you didn't use an emulator or VM, post the following:

- What value did you send to 0xcf8, what value did you read from 0xcfc, and what instructions did you use to do that?
- How did you, with explanations and citing sources, calculate the value you sent to port 0xcf8?


1.Does pci bus and device needs insitalization
The BIOS configures the PCI bus and makes sure config space works. You don't need to initialize individual devices for what you want to do.
3. in "pci.h" struct pci_dev{...} who initializes or maps the sub field of this struct data type.
Any #include of linux code into your own bootloader is wrong. period.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
nuralam89
Posts: 5
Joined: Mon Feb 09, 2015 4:53 am

what type of information Base Address Register(BAR) provides

Post by nuralam89 »

hi,
what type of information Base Address Register(BAR) provides??is it a Address range of a device? or Starting adress address?

actually i am trying to
implement a tiny bootable piece of code(a kind of small Operating
system) through which(by writing code) i want to access data from hard
disk.

If it(BAR) provides Address ranges of a device then what should be a starting address.

P.S.: using following code i have got a number other than zero from only BAR no-05 i.e. offset 0x24.


#include<stdio.h>
#include<stdlib.h>
//#include<linux/pci.h>
#include<sys/io.h>
//#include<kernel/pci.h>

#define INDEX_PCI 0xCF8
#define DATA_PCI 0xCFC

long __read_PCI_config (long _devvid, int _offset); //Function prototype
void value(long _devvid,int _offset);

void main (void)
{
unsigned int i;
printf("\n in main \n ");
printf("\n val= %x",__read_PCI_config(0x2363197b,0x00));//where 0x2363 & 197b is the deviceID and vendorID of my SATA Controller
printf("\n i= %d \n",i);
value(0x2363197b,0x24);
printf("\n i= %d\n",i);
}


long __read_PCI_config (long _devvid, int _offset)
// This function will return the data from the supplied offset into the PCI configuration
// space of the first device found that matches the supplied Device and Vendor ID or zero
// if no match is found.
{
long scankey;
int bus, device, function,i;

printf("\n in read pci");
fflush(stdout);
i=iopl(3);

//printf("\n value of ioperm ret =%d",i);

//Search each bus, device, function...
for(bus = 0; bus < 256; bus++)
{
for(device = 0; device < 32; device++)
{
for(function = 0;function < 8; function++)
{
outl((8 << 28 | bus << 16 | device << 11 | function << 8 ),INDEX_PCI);
i=iopl(3);
//printf("\n the value of iopl return in OUTL is= %d",i);
scankey = inl(0xCFC);
//printf("\n the valscan key = %x ",scankey);
if (scankey == _devvid)
{
printf("\n Device found");
// value(scankey,0x01);
outl(( (8 << 28 | bus << 16 | device << 11 | function << 8 ) + _offset),INDEX_PCI);
return inl( DATA_PCI );
}
}

}
}
//printf("\n ioperm for CFC =%d",i);
printf("\n scan key= %u",scankey);


//No Match
return 0L;
}



long read_PCI_config (long _devvid, int _offset)
// This function will return the data from the supplied offset into the PCI configuration
// space of the first device found that matches the supplied Device and Vendor ID or zero
// if no match is found.
{
long scankey;
int bus, device, function,i;

//printf("\n in read pci");
fflush(stdout);
i=iopl(3);
for(bus=0;bus<256;bus++)
{
for(device = 0; device < 32; device++)
{
for(function = 0;function < 8; function++)
{
outl((8 << 28 | bus << 16 | device << 11 | function << 8 ),INDEX_PCI);
i=iopl(3);
//printf("\n the value of iopl return in OUTL is= %d",i);
scankey = inl(0xCFC);
//printf("\n the valscan key = %x ",scankey);
if (scankey == _devvid)
{
printf("\n Device found");

outl(( (8 << 28 | bus << 16 | device << 11 | function << 8 ) +0x24),INDEX_PCI);
return inl( DATA_PCI );
}
}

}
}
//printf("\n ioperm for CFC =%d",i);
printf("\n scan key= %x",scankey);


//No Match
return 0L;
}



void value(long _devvid,int _offset)
{
int i;
i=iopl(3);
printf("\n ReturnValue in Value Function= %x",read_PCI_config(0x2363197b,0x24));

}
********************************************************************************************************************************************************
OUTPUT
********************************************************************************************************************************************************
in main

in read pci
Device found
val= 2363197b
i= 0

Device found
ReturnValue in Value Function= feafe000
i= 0

BEFORE WRITE INL VALUE IS:feafe000
AT=feafe000
The INL VALUE is:feafe000
Device found
After Write Return value is:=feafe000
**********************************************************************************************************************************************************

my query is what is the significance of this '0xfeafe000' which i have got from BAR 05 i.e. offset 0x24.
Octocontrabass
Member
Member
Posts: 5588
Joined: Mon Mar 25, 2013 7:01 pm

Re: unable to read pci config address(0xcfc) data;

Post by Octocontrabass »

nuralam89 wrote:iopl(3);
Why are you still picking a fight with the linux kernel and not using lspci?
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: unable to read pci config address(0xcfc) data;

Post by Combuster »

Please take in consideration the forum rules that ask you to search before posting: http://wiki.osdev.org/PCI#Base_Address_Registers, and to use tags
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Post Reply