Changeset 3a5909f in mainline for uspace/srv/drivers/pciintel/pci.c


Ignore:
Timestamp:
2010-04-09T11:46:56Z (14 years ago)
Author:
Lenka Trochtova <trochtova.lenka@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
3843ecb
Parents:
d1fc8f0
Message:

pci bus enumeration - bars and ints

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/drivers/pciintel/pci.c

    rd1fc8f0 r3a5909f  
    5555
    5656#include "pci.h"
    57 #include "pci_regs.h"
    5857
    5958#define NAME "pciintel"
     
    181180void pci_conf_write_8(device_t *dev, int reg, uint8_t val)
    182181{
    183         pci_conf_write(dev, reg, (uint8_t *)&val, 4);   
     182        pci_conf_write(dev, reg, (uint8_t *)&val, 1);   
    184183}
    185184
    186185void pci_conf_write_16(device_t *dev, int reg, uint16_t val)
    187186{
    188         pci_conf_write(dev, reg, (uint8_t *)&val, 4);   
     187        pci_conf_write(dev, reg, (uint8_t *)&val, 2);   
    189188}
    190189
     
    208207}
    209208
    210 
    211 static size_t range_size_form_mask(uint32_t mask)
    212 {
    213         // TODO
    214         return 0;
    215 }
     209void pci_add_range(device_t *dev, uint64_t range_addr, size_t range_size, bool io)
     210{
     211        pci_dev_data_t *dev_data = (pci_dev_data_t *)dev->driver_data;
     212        hw_resource_list_t *hw_res_list = &dev_data->hw_resources;
     213        hw_resource_t *hw_resources =  hw_res_list->resources;
     214        size_t count = hw_res_list->count;     
     215       
     216        assert(NULL != hw_resources);
     217        assert(count < PCI_MAX_HW_RES);
     218       
     219        if (io) {
     220                hw_resources[count].type = IO_RANGE;
     221                hw_resources[count].res.io_range.address = range_addr;
     222                hw_resources[count].res.io_range.size = range_size;     
     223                hw_resources[count].res.io_range.endianness = LITTLE_ENDIAN;   
     224        } else {
     225                hw_resources[count].type = MEM_RANGE;
     226                hw_resources[count].res.mem_range.address = range_addr;
     227                hw_resources[count].res.mem_range.size = range_size;   
     228                hw_resources[count].res.mem_range.endianness = LITTLE_ENDIAN;
     229        }
     230       
     231        hw_res_list->count++;   
     232}
     233
    216234
    217235/** Read the base address register (BAR) of the device
     
    223241 * @return the addr the address of the BAR which should be read next.
    224242 */
    225 static int pci_read_bar(device_t *dev, int addr)
     243int pci_read_bar(device_t *dev, int addr)
    226244{       
    227245        // value of the BAR
     
    237255        uint64_t range_addr;
    238256       
    239        
     257        // get the value of the BAR
    240258        val = pci_conf_read_32(dev, addr);
    241259       
     
    263281        // restore the original value
    264282        pci_conf_write_32(dev, addr, val);
    265        
    266         range_size = range_size_form_mask(mask);
     283        val = pci_conf_read_32(dev, addr);     
     284       
     285        range_size = pci_bar_mask_to_size(mask);
    267286       
    268287        if (w64) {
     
    272291        }       
    273292        if (0 != range_addr) {
    274                 printf(NAME ": device address = %x\n", range_addr);     
    275         }
    276        
    277         // TODO add to the HW resource list
     293                printf(NAME ": device %s : ", dev->name);
     294                printf("address = %x", range_addr);             
     295                printf(", size = %x\n", range_size);
     296        }
     297       
     298        pci_add_range(dev, range_addr, range_size, io);
    278299       
    279300        if (w64) {
     
    283304}
    284305
    285 /** Read the base address registers (BARs) of the device
    286  *  and adds the addresses to its hw resource list.
    287  *
    288  * @param dev the pci device.
    289  */
    290 static void pci_read_bars(device_t *dev)
    291 {
    292         // position of the BAR in the PCI configuration address space of the device
    293         int addr = PCI_BASE_ADDR_0;
    294        
    295         while (addr <= PCI_BASE_ADDR_5) {
    296                 addr = pci_read_bar(dev, addr);
     306void pci_add_interrupt(device_t *dev, int irq)
     307{
     308        pci_dev_data_t *dev_data = (pci_dev_data_t *)dev->driver_data;
     309        hw_resource_list_t *hw_res_list = &dev_data->hw_resources;
     310        hw_resource_t *hw_resources =  hw_res_list->resources;
     311        size_t count = hw_res_list->count;     
     312       
     313        assert(NULL != hw_resources);
     314        assert(count < PCI_MAX_HW_RES);
     315       
     316        hw_resources[count].type = INTERRUPT;
     317        hw_resources[count].res.interrupt.irq = irq;
     318       
     319        hw_res_list->count++;           
     320       
     321       
     322        printf(NAME ": device %s uses irq %x.\n", dev->name, irq);
     323}
     324
     325void pci_read_interrupt(device_t *dev)
     326{
     327        uint8_t irq = pci_conf_read_8(dev, PCI_BRIDGE_INT_LINE);
     328        if (0xff != irq) {
     329                pci_add_interrupt(dev, irq);
    297330        }       
    298331}
     
    321354                        dev_data->vendor_id = pci_conf_read_16(dev, PCI_VENDOR_ID);
    322355                        dev_data->device_id = pci_conf_read_16(dev, PCI_DEVICE_ID);
    323                         if (dev_data->vendor_id == 0xFFFF) { // device is not present, go on scanning the bus
     356                        if (dev_data->vendor_id == 0xffff) { // device is not present, go on scanning the bus
    324357                                if (fnum == 0) {
    325358                                        break;
     
    334367                        header_type = header_type & 0x7F; // clear the multifunction bit
    335368                       
    336                         // TODO initialize device - interfaces, hw resources
     369                        create_pci_dev_name(dev);
     370                       
     371                        pci_alloc_resource_list(dev);
    337372                        pci_read_bars(dev);
    338                        
    339                         create_pci_dev_name(dev);
     373                        pci_read_interrupt(dev);
     374                       
     375                        // TODO initialize device interfaces                   
     376                       
    340377                        printf(NAME ": adding new child device %s.\n", dev->name);
    341378                       
    342379                        create_pci_match_ids(dev);
    343380                       
    344                         if (!child_device_register(dev, parent)) {
     381                        if (!child_device_register(dev, parent)) {                             
     382                                pci_clean_resource_list(dev);                           
    345383                                clean_match_ids(&dev->match_ids);
    346384                                free((char *)dev->name);
     
    366404        }
    367405       
    368         if (dev_data->vendor_id == 0xFFFF) {
     406        if (dev_data->vendor_id == 0xffff) {
    369407                delete_device(dev);
    370408                delete_pci_dev_data(dev_data);  // free the auxiliary device structure
    371         }       
    372        
     409        }               
    373410}
    374411
     
    397434                ipc_hangup(dev->parent_phone);
    398435                return false;           
    399         }
    400        
    401        
    402         printf(NAME ": conf_addr = %x.\n", hw_resources.resources[0].res.reg.address); 
     436        }       
     437       
     438        printf(NAME ": conf_addr = %x.\n", hw_resources.resources[0].res.io_range.address);     
    403439       
    404440        assert(hw_resources.count > 0);
    405         assert(hw_resources.resources[0].type == REGISTER);
    406         assert(hw_resources.resources[0].res.reg.size == 8);
    407        
    408         bus_data->conf_io_addr = (uint32_t)hw_resources.resources[0].res.reg.address;
     441        assert(hw_resources.resources[0].type == IO_RANGE);
     442        assert(hw_resources.resources[0].res.io_range.size == 8);
     443       
     444        bus_data->conf_io_addr = (uint32_t)hw_resources.resources[0].res.io_range.address;
    409445       
    410446        if (pio_enable((void *)bus_data->conf_io_addr, 8, &bus_data->conf_addr_port)) {
Note: See TracChangeset for help on using the changeset viewer.