PCI Scanning (continued from Enumarating USB)

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.
User avatar
naiksidd_85
Member
Member
Posts: 76
Joined: Thu Jan 17, 2008 1:15 am

PCI Scanning (continued from Enumarating USB)

Post by naiksidd_85 »

hi all,

as the most meaningful solution to Enumerating USB is to scan PCI bus (as commented by many OSdevers).
I thought I should create a new topic and start over with PCI first.

I did try many things like outs to 0xcf8 but still the output is 0xff i am not sure why am i not able to read the BARS.
pls help me in it . :oops:
Learning a lot these days THANKS to OSdev users
Laksen
Member
Member
Posts: 140
Joined: Fri Nov 09, 2007 3:30 am
Location: Aalborg, Denmark

Re: PCI Scanning (continued from Enumarating USB)

Post by Laksen »

I just used the PCI Bios to do all PCI detection and reading handling. It's pretty easy to use
http://j-software.dk | JPasKernel - My Object Pascal kernel
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: PCI Scanning (continued from Enumarating USB)

Post by Combuster »

do you even get a list of hardware?
"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 ]
User avatar
naiksidd_85
Member
Member
Posts: 76
Joined: Thu Jan 17, 2008 1:15 am

Re: PCI Scanning (continued from Enumarating USB)

Post by naiksidd_85 »

do you even get a list of hardware?
yes i do get it... As i had said in my post, but using SMBIOS.
Learning a lot these days THANKS to OSdev users
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: PCI Scanning (continued from Enumarating USB)

Post by Combuster »

You should really test for harware being actually present before even trying to list their BARs.

Any code?
"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 ]
User avatar
naiksidd_85
Member
Member
Posts: 76
Joined: Thu Jan 17, 2008 1:15 am

Re: PCI Scanning (continued from Enumarating USB)

Post by naiksidd_85 »

I am trying the code very similar to what you had posted...

Code: Select all

   
 dword value;
    for (int i = 0; i < 32; i++)
    {
        out32 (0xCF8, (i << 11) | 0x80000000);
        value = in32(0xCFC);
        if (value != 0xffffffff && value != 0)
        {
            printf("Device found in slot %i: %x\r\n", i, value);
        }
    }
just with some changes that is the function names changing but i am not really clear why we outs the value ox80000000 here I have also read that we need to write 0xffffffff to 0xCF8 and read from it.....
will first try to find what hardware is connected as you commented.
sorry for asking such irritating question but I am completely Lost...
Learning a lot these days THANKS to OSdev users
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: PCI Scanning (continued from Enumarating USB)

Post by Combuster »

I think you're seeing ghosts. PCI has all the info you need.
i am not really clear why we outs the value ox80000000
Bit 31 is an enable flag for determining when accesses to CONFIG_DATA should be translated to configuration cycles.
write 0xffffffff to 0xCF8
Ghost #1
0xCF8 and read from it
Ghost #2. Any information comes from the data port - 0xCFC
sorry for asking such irritating question but I am completely Lost...
It helps if you start from point zero. You're like omg i wrote 5000 lines of code and it doesnt work and i dont know whats happening and it does not work and im lost like a headless chicken help me. Nobody (except psychics, which we aren't) can solve your problem that way. Try imagining why. Begin with the basics. Write 10 lines of code, test it, add a few more, test it, add even more, oops those last 5 lines broke it. Then you know where to look for an answer.
"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 ]
User avatar
Jeko
Member
Member
Posts: 500
Joined: Fri Mar 17, 2006 12:00 am
Location: Napoli, Italy

Re: PCI Scanning (continued from Enumarating USB)

Post by Jeko »

You can also read source code of other operating systems. It's really useful to understand better how things work.
User avatar
lukem95
Member
Member
Posts: 536
Joined: Fri Aug 03, 2007 6:03 am
Location: Cambridge, UK

Re: PCI Scanning (continued from Enumarating USB)

Post by lukem95 »

Code: Select all

typedef struct
{
unsigned short VendorID;  
unsigned short DeviceID;
unsigned short CommandReg;
unsigned short StatusReg;
unsigned char RevisionID;
unsigned char ProgIF;
unsigned char SubClass;
unsigned char ClassCode;
unsigned char CachelineSize;
unsigned char Latency;
unsigned char HeaderType;
unsigned char BIST;

unsigned int BAR0; //Base Address Register
unsigned int BAR1;
unsigned int BAR2;
unsigned int BAR3;
unsigned int BAR4;
unsigned int BAR5;
unsigned int CardbusCISPtr;
unsigned short SubVendorID; //Subsystem
unsigned short SubDeviceID;
unsigned int ExRomAddress; //Expansion ROM
unsigned int Reserved1;
unsigned int Reserved2;
unsigned char IRQ; //IRQ number
unsigned char PIN; //IRQ PIN number
unsigned char MinGrant;
unsigned char MaxLatency;
} PCI_Device_t;

Code: Select all

//Reads DWORD config register
static u32int pci_read(int bus, int dev, int func, int reg)
{
  outl(0xCF8,
	    ((unsigned long) 0x80000000 | (bus << 16) | (dev << 11) |
	     (func << 8) | reg));
  return inl(0xCFC);
}


PCI_Device_t* ret;

static PCI_Device_t* pci_readdevice(int bus, int dev, int func)
{ 
   PCI_Device_t* ret;

  //THIS FUNCTION HAS BEEN LEFT BLANK
  //sorry... but i dont want you just leeching code if you're not going understand
  //TODO: get each 32bit value from pci_read() and put it in the correct place in the
  //PCI_Device_t struct.
  
  return ret;
}

Code: Select all

PCI_Device_t * dev;
dev = pci_readdevice(bus, device, function);

if(dev->ClassCode == 0x0C && dev->SubClass == 0x03)
{
     kprintf("we g0tz our USB controller");
     kprintf("IRQ: %d BAR0: 0x%x BAR1: 0x%x ...\n",dev->IRQ,dev->BAR0,dev->BAR1);
}

This is similar to the code i use (the struct is the same, as is pci_read()), i've left one of the functions blank, but if you understand the code (and read the wiki) you will be able to write your own implementation in about 10 minutes (including debugging)... i've actually only removed 3 lines of code.

anyway, hope this helps a bit
~ Lukem95 [ Cake ]
Release: 0.08b
Image
User avatar
naiksidd_85
Member
Member
Posts: 76
Joined: Thu Jan 17, 2008 1:15 am

Re: PCI Scanning (continued from Enumarating USB)

Post by naiksidd_85 »

hi all,

I finally found out what was going wrong when i wrote the entire code again..
i was really foolish (or i would say stressed out), i was reading 16bit value and writing 32bit address but now am able to read the pci ,
thanx
Learning a lot these days THANKS to OSdev users
User avatar
raistlinthewiz
Member
Member
Posts: 34
Joined: Wed Jun 29, 2005 11:00 pm
Contact:

Re: PCI Scanning (continued from Enumarating USB)

Post by raistlinthewiz »

i try to fill in the code but having strange errors;

Code: Select all

static pci_device_t* pci_read_device(int bus, int dev, int func)
{
   pci_device_t* ret;


   ret->VendorID=pci_read(bus,dev,func,0);	
   ret->DeviceID=pci_read(bus,dev,func,2);	
   
   //ret->CommandReg=pci_read(bus,dev,func,4);
   //ret->ClassCode=pci_read(bus,dev,func,8);
 
   return ret;
}
does not work for DeviceID? any suggestions?
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: PCI Scanning (continued from Enumarating USB)

Post by Combuster »

alignment issues - reading 4 bytes from offset 2 perchance?
"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 ]
User avatar
raistlinthewiz
Member
Member
Posts: 34
Joined: Wed Jun 29, 2005 11:00 pm
Contact:

Re: PCI Scanning (continued from Enumarating USB)

Post by raistlinthewiz »

if u use a dword version,

ret->VendorID=pci_read_dword(bus,dev,func,0);
ret->DeviceID=pci_read_dword(bus,dev,func,2);

vendorid gets corrupted...
can't fix it. any ideas?
User avatar
Masterkiller
Member
Member
Posts: 153
Joined: Sat May 05, 2007 6:20 pm

Re: PCI Scanning (continued from Enumarating USB)

Post by Masterkiller »

raistlinthewiz wrote:if u use a dword version,

ret->VendorID=pci_read_dword(bus,dev,func,0);
ret->DeviceID=pci_read_dword(bus,dev,func,2);

vendorid gets corrupted...
can't fix it. any ideas?
By Default last two bits are reserved and must be written to zero. The PCI I/O register you read muse be 0x04 aligned and read as a dword. So you read both Vendor and Device ID at once. You must use Arithmetic-Logical function to separate it. Here is the code for C:

Code: Select all

ret->VendorID = (short)((pci_read_dword(bus,dev,func,0)&0xFFFF0000)>>16); //Read VendorID and DeviceID, zero the DeviceID and shift VendorID to the lower word
ret->DeviceID = (short)(pci_read_dword(bus,dev,func,0)&0x0000FFFF); //Read VendorID and DeviceID again and zero the VendorID
ALCA OS: Project temporarity suspended!
Current state: real-mode kernel-FS reader...
User avatar
raistlinthewiz
Member
Member
Posts: 34
Joined: Wed Jun 29, 2005 11:00 pm
Contact:

Re: PCI Scanning (continued from Enumarating USB)

Post by raistlinthewiz »

thanks a lot it did worked, for future reference, just the correct order is;

Code: Select all

		 
ret->VendorID = (uint16) (pci_read(bus,dev,func,0)&0x0000FFFF); //Read VendorID and DeviceID, zero the DeviceID and shift VendorID to the lower word
ret->DeviceID = (uint16)((pci_read(bus,dev,func,0)&0xFFFF0000) >> 16); //Read VendorID and DeviceID again and zero the VendorID
and pci_read_word did not worked but instead i used uint32 version;

Code: Select all

uint32 pci_read(int bus, int dev, int func, int reg)
{
  outl(0xCF8,((unsigned long) 0x80000000 | (bus << 16) | (dev << 11) | (func << 8) | reg ));
  return inl(0xCFC);
}
Post Reply