OSDev.org

The Place to Start for Operating System Developers
It is currently Wed Sep 23, 2020 6:59 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 7 posts ] 
Author Message
 Post subject: I can't get classID of PCI device.
PostPosted: Sat Apr 18, 2020 8:13 pm 
Offline
Member
Member

Joined: Wed Feb 13, 2019 3:07 pm
Posts: 28
hi, i write pci driver. but my function get_class_id returns 0x0 for all detected device.


Code:
u16 get_class_id(u16 bus, u16 device, u16 function)
{
        u32 r0 = pci_read_word(bus,device,function,0xa);
        return (r0 & ~0x00FF) >> 8;
}


full code - https://github.com/s04v/OSv1.0/blob/mas ... vers/pci.c

how to solve this problem?


Top
 Profile  
 
 Post subject: Re: I can't get classID of PCI device.
PostPosted: Sat Apr 18, 2020 9:13 pm 
Offline
Member
Member

Joined: Wed Aug 30, 2017 8:24 am
Posts: 625
That is a misaligned read. The offset always needs to be divisible by 4, meaning in hex it always has to end in 0, 4, 8, or C. In your case:
Code:
u16 get_class_id(u16 bus, u16 device, u16 function)
{
        u32 r0 = pci_read_word(bus,device,function,0x8);
        return (r0 >> 24) & 0xFF;
}

_________________
Life is beautiful. Nobody said easy.


Top
 Profile  
 
 Post subject: Re: I can't get classID of PCI device.
PostPosted: Sat Apr 18, 2020 11:56 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 2297
You shouldn't copy someone else's code if you don't understand it.

I suspect this mistake originates in the wiki, where the example function reads 16-bit words despite configuration mechanism 1 functioning exclusively in 32-bit dwords.


Top
 Profile  
 
 Post subject: Re: I can't get classID of PCI device.
PostPosted: Sun Apr 19, 2020 3:17 am 
Offline
Member
Member

Joined: Wed Feb 13, 2019 3:07 pm
Posts: 28
nullplan wrote:
That is a misaligned read. The offset always needs to be divisible by 4, meaning in hex it always has to end in 0, 4, 8, or C. In your case:
Code:
u16 get_class_id(u16 bus, u16 device, u16 function)
{
        u32 r0 = pci_read_word(bus,device,function,0x8);
        return (r0 >> 24) & 0xFF;
}


It's not working correctly


Top
 Profile  
 
 Post subject: Re: I can't get classID of PCI device.
PostPosted: Sun Apr 19, 2020 3:22 am 
Offline
Member
Member

Joined: Wed Feb 13, 2019 3:07 pm
Posts: 28
Octocontrabass wrote:
You shouldn't copy someone else's code if you don't understand it.

I suspect this mistake originates in the wiki, where the example function reads 16-bit words despite configuration mechanism 1 functioning exclusively in 32-bit dwords.



where can i find correct function definition?
I take it there's a problem with this line?
Code:
tmp = (u16)((inw(0xCFC) >> ((offset & 2) * 8)) & 0xffff);


Top
 Profile  
 
 Post subject: Re: I can't get classID of PCI device.
PostPosted: Sun Apr 19, 2020 10:26 pm 
Offline
Member
Member

Joined: Wed Sep 01, 2010 3:54 pm
Posts: 36
Shvets04 wrote:
Octocontrabass wrote:
You shouldn't copy someone else's code if you don't understand it.

I suspect this mistake originates in the wiki, where the example function reads 16-bit words despite configuration mechanism 1 functioning exclusively in 32-bit dwords.



where can i find correct function definition?
I take it there's a problem with this line?
Code:
tmp = (u16)((inw(0xCFC) >> ((offset & 2) * 8)) & 0xffff);


My guess would probably be inw, which is defined as u16 inw(u16 port) in your port.h. Those ports read and write 32 bits, so you read the full int and then break it up. This is how I do it in my OS, but my code isn't C/C++.

Code:
let (device_id, vendor_id) = read_2_words(address, 0x00);

fn read_2_words(address: u32, offset: u32) -> (u16, u16) {
    let value = read_offset(address, offset);
    let high_word = (value >> 16) as u16;
    let low_word = value as u16;
    (high_word, low_word)
}

fn read_offset(mut address: u32, offset: u32) -> u32 {
    let mut config_address = Port::new(CONFIG_ADDRESS);
    let mut data_address = Port::new(DATA_ADDRESS);
    address |= offset & 0xFC;
    unsafe {
        config_address.write(address);
        data_address.read()
    }
}


Top
 Profile  
 
 Post subject: Re: I can't get classID of PCI device.
PostPosted: Mon May 04, 2020 8:03 am 
Offline
Member
Member

Joined: Sat Mar 10, 2018 10:16 am
Posts: 170
Code:
u16 pci_read_word(u8 bus, u8 slot, u8 func, u8 offset)
{
   u32 address;
    u32 lbus = (u32)bus;
    u32 lslot = (u32)slot;
    u32 lfunc = (u32)func;
    u16 tmp = 0;
    address = (u32)((lbus << 16) | (lslot << 11) |
              (lfunc << 8) | (offset & 0xfc) | ((u32)0x80000000));
    outw(0xCF8, address);
    tmp = (u16)((inw(0xCFC) >> ((offset & 2) * 8)) & 0xffff);
    return (tmp);
}


You must use outl and inl functions.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot] and 10 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group