Changeset 3a5909f in mainline


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

Location:
uspace
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/libc/include/ipc/dev_iface.h

    rd1fc8f0 r3a5909f  
    6060typedef enum {
    6161        INTERRUPT,
    62         REGISTER
     62        IO_RANGE,
     63        MEM_RANGE
    6364} hw_res_type_t;
    6465
     
    7677                        endianness_t endianness;                       
    7778                        size_t size;                   
    78                 } reg;
     79                } mem_range;
     80                struct {
     81                        uint64_t address;
     82                        endianness_t endianness;                       
     83                        size_t size;                   
     84                } io_range;
    7985                struct {
    8086                        int irq;                       
    81                 } intr;         
     87                } interrupt;           
    8288        } res; 
    8389} hw_resource_t;
  • 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)) {
  • uspace/srv/drivers/pciintel/pci.h

    rd1fc8f0 r3a5909f  
    4141#include <malloc.h>
    4242
     43#include "pci_regs.h"
     44
     45#define PCI_MAX_HW_RES 8
     46
    4347typedef struct pci_dev_data {
    4448        int bus;
     
    4953        hw_resource_list_t hw_resources;
    5054} pci_dev_data_t;
     55
     56void create_pci_match_ids(device_t *dev);
     57
     58uint8_t pci_conf_read_8(device_t *dev, int reg);
     59uint16_t pci_conf_read_16(device_t *dev, int reg);
     60uint32_t pci_conf_read_32(device_t *dev, int reg);
     61void pci_conf_write_8(device_t *dev, int reg, uint8_t val);
     62void pci_conf_write_16(device_t *dev, int reg, uint16_t val);
     63void pci_conf_write_32(device_t *dev, int reg, uint32_t val);
     64
     65void pci_add_range(device_t *dev, uint64_t range_addr, size_t range_size, bool io);
     66int pci_read_bar(device_t *dev, int addr);
     67void pci_read_interrupt(device_t *dev);
     68void pci_add_interrupt(device_t *dev, int irq);
     69
     70void pci_bus_scan(device_t *parent, int bus_num);
     71
    5172
    5273static inline pci_dev_data_t *create_pci_dev_data()
     
    82103}
    83104
    84 void create_pci_match_ids(device_t *dev);
     105static inline bool pci_alloc_resource_list(device_t *dev)
     106{
     107        pci_dev_data_t *dev_data = (pci_dev_data_t *)dev->driver_data;
     108        dev_data->hw_resources.resources = (hw_resource_t *)malloc(PCI_MAX_HW_RES * sizeof(hw_resource_t));
     109        return dev_data->hw_resources.resources != NULL;       
     110}
    85111
    86 uint8_t pci_conf_read_8(device_t *dev, int reg);
    87 uint16_t pci_conf_read_16(device_t *dev, int reg);
    88 uint32_t pci_conf_read_32(device_t *dev, int reg);
    89 void pci_conf_write_8(device_t *dev, int reg, uint8_t val);
    90 void pci_conf_write_16(device_t *dev, int reg, uint16_t val);
    91 void pci_conf_write_32(device_t *dev, int reg, uint32_t val);
     112static inline bool pci_clean_resource_list(device_t *dev)
     113{
     114        pci_dev_data_t *dev_data = (pci_dev_data_t *)dev->driver_data;
     115        if (NULL != dev_data->hw_resources.resources) {
     116                free(dev_data->hw_resources.resources);
     117                dev_data->hw_resources.resources = NULL;
     118        }
     119}
    92120
    93 void pci_bus_scan(device_t *parent, int bus_num);
     121/** Read the base address registers (BARs) of the device
     122 *  and adds the addresses to its hw resource list.
     123 *
     124 * @param dev the pci device.
     125 */
     126static inline  void pci_read_bars(device_t *dev)
     127{
     128        // position of the BAR in the PCI configuration address space of the device
     129        int addr = PCI_BASE_ADDR_0;
     130       
     131        while (addr <= PCI_BASE_ADDR_5) {
     132                addr = pci_read_bar(dev, addr);
     133        }       
     134}
     135
     136static inline size_t pci_bar_mask_to_size(uint32_t mask)
     137{
     138        return ((mask & 0xfffffff0) ^ 0xffffffff) + 1;
     139}
     140
    94141
    95142#endif
  • uspace/srv/drivers/rootia32/rootia32.c

    rd1fc8f0 r3a5909f  
    7575
    7676static hw_resource_t pci_conf_regs = {
    77         .type = REGISTER,
    78         .res.reg = {
    79                 .address = (void *)0xCF8,
     77        .type = IO_RANGE,
     78        .res.io_range = {
     79                .address = 0xCF8,
    8080                .size = 8,
    8181                .endianness = LITTLE_ENDIAN     
Note: See TracChangeset for help on using the changeset viewer.