Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset d1fc8f0 in mainline


Ignore:
Timestamp:
2010-04-08T20:32:33Z (12 years ago)
Author:
Lenka Trochtova <trochtova.lenka@…>
Branches:
lfn, master
Children:
3a5909f
Parents:
2480e19
Message:

pci base address registers reading - parts of code

Location:
uspace
Files:
3 edited

Legend:

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

    r2480e19 rd1fc8f0  
    3333#include <malloc.h>
    3434#include <unistd.h>
     35#include <libarch/types.h>
    3536
    3637#define DEV_IFACE_FIRST IPC_FIRST_USER_METHOD
     
    7273        union {
    7374                struct {
    74                         void *address;
     75                        uint64_t address;
    7576                        endianness_t endianness;                       
    7677                        size_t size;                   
  • uspace/srv/drivers/pciintel/pci.c

    r2480e19 rd1fc8f0  
    7979
    8080typedef struct pciintel_bus_data {
    81         void *conf_io_addr;
     81        uint32_t conf_io_addr;
    8282        void *conf_data_port;
    8383        void *conf_addr_port;   
     
    129129}
    130130
     131static void pci_conf_write(device_t *dev, int reg, uint8_t *buf, size_t len)
     132{
     133        assert(NULL != dev->parent);
     134       
     135        pci_dev_data_t *dev_data = (pci_dev_data_t *)dev->driver_data;
     136        pci_bus_data_t *bus_data = (pci_bus_data_t *)dev->parent->driver_data;
     137       
     138        fibril_mutex_lock(&bus_data->conf_mutex);
     139       
     140        uint32_t conf_addr =  CONF_ADDR(dev_data->bus, dev_data->dev, dev_data->fn, reg);
     141        void *addr = bus_data->conf_data_port + (reg & 3);
     142       
     143        pio_write_32(bus_data->conf_addr_port, conf_addr);
     144       
     145        switch (len) {
     146                case 1:
     147                        pio_write_8(addr, buf[0]);
     148                        break;
     149                case 2:
     150                        pio_write_16(addr, ((uint16_t *)buf)[0]);
     151                        break;
     152                case 4:
     153                        pio_write_32(addr, ((uint32_t *)buf)[0]);
     154                        break;
     155        }
     156       
     157        fibril_mutex_unlock(&bus_data->conf_mutex);     
     158}
     159
    131160uint8_t pci_conf_read_8(device_t *dev, int reg)
    132161{
     
    149178        return res;     
    150179}
     180
     181void pci_conf_write_8(device_t *dev, int reg, uint8_t val)
     182{
     183        pci_conf_write(dev, reg, (uint8_t *)&val, 4);   
     184}
     185
     186void pci_conf_write_16(device_t *dev, int reg, uint16_t val)
     187{
     188        pci_conf_write(dev, reg, (uint8_t *)&val, 4);   
     189}
     190
     191void pci_conf_write_32(device_t *dev, int reg, uint32_t val)
     192{
     193        pci_conf_write(dev, reg, (uint8_t *)&val, 4);   
     194}
     195
    151196
    152197void create_pci_match_ids(device_t *dev)
     
    164209
    165210
     211static size_t range_size_form_mask(uint32_t mask)
     212{
     213        // TODO
     214        return 0;
     215}
     216
     217/** Read the base address register (BAR) of the device
     218 *  and if it contains valid address add it to the devices hw resource list.
     219 *
     220 * @param dev the pci device.
     221 * @param addr the address of the BAR in the PCI configuration address space of the device.
     222 *
     223 * @return the addr the address of the BAR which should be read next.
     224 */
     225static int pci_read_bar(device_t *dev, int addr)
     226{       
     227        // value of the BAR
     228        uint32_t val, mask;
     229        // IO space address
     230        bool io;
     231        // 64-bit wide address
     232        bool w64;
     233       
     234        // size of the io or memory range specified by the BAR
     235        size_t range_size;
     236        // beginning of the io or memory range specified by the BAR
     237        uint64_t range_addr;
     238       
     239       
     240        val = pci_conf_read_32(dev, addr);
     241       
     242        io = (bool)(val & 1);
     243        if (io) {
     244                w64 = false;
     245        } else {
     246                switch ((val >> 1) & 3) {
     247                case 0:
     248                        w64 = false;
     249                        break;
     250                case 2:
     251                        w64 = true;
     252                        break;
     253                default:
     254                        // reserved, go to the next BAR
     255                        return addr + 4;                                                       
     256                }
     257        }
     258       
     259        // get the address mask
     260        pci_conf_write_32(dev, addr, 0xffffffff);
     261        mask = pci_conf_read_32(dev, addr);     
     262       
     263        // restore the original value
     264        pci_conf_write_32(dev, addr, val);
     265       
     266        range_size = range_size_form_mask(mask);
     267       
     268        if (w64) {
     269                range_addr = ((uint64_t)pci_conf_read_32(dev, addr + 4) << 32) | (val & 0xfffffff0);   
     270        } else {
     271                range_addr = (val & 0xfffffff0);
     272        }       
     273        if (0 != range_addr) {
     274                printf(NAME ": device address = %x\n", range_addr);     
     275        }
     276       
     277        // TODO add to the HW resource list
     278       
     279        if (w64) {
     280                return addr + 8;
     281        }
     282        return addr + 4;       
     283}
     284
     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 */
     290static 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);
     297        }       
     298}
     299
     300/** Enumerate (recursively) and register the devices connected to a pci bus.
     301 *
     302 * @param parent the host-to-pci bridge device.
     303 * @param bus_num the bus number.
     304 */
    166305void pci_bus_scan(device_t *parent, int bus_num)
    167306{
     
    174313        int dnum, fnum;
    175314        bool multi;
    176         uint8_t header_type;
     315        uint8_t header_type; 
    177316       
    178317        for (dnum = 0; dnum < 32; dnum++) {
     
    196335                       
    197336                        // TODO initialize device - interfaces, hw resources
     337                        pci_read_bars(dev);
    198338                       
    199339                        create_pci_dev_name(dev);
     
    266406        assert(hw_resources.resources[0].res.reg.size == 8);
    267407       
    268         bus_data->conf_io_addr = hw_resources.resources[0].res.reg.address;
    269        
    270         if (pio_enable(bus_data->conf_io_addr, 8, &bus_data->conf_addr_port)) {
     408        bus_data->conf_io_addr = (uint32_t)hw_resources.resources[0].res.reg.address;
     409       
     410        if (pio_enable((void *)bus_data->conf_io_addr, 8, &bus_data->conf_addr_port)) {
    271411                printf(NAME ": failed to enable configuration ports.\n");
    272412                delete_pci_bus_data(bus_data);
  • uspace/srv/drivers/pciintel/pci.h

    r2480e19 rd1fc8f0  
    8787uint16_t pci_conf_read_16(device_t *dev, int reg);
    8888uint32_t pci_conf_read_32(device_t *dev, int reg);
     89void pci_conf_write_8(device_t *dev, int reg, uint8_t val);
     90void pci_conf_write_16(device_t *dev, int reg, uint16_t val);
     91void pci_conf_write_32(device_t *dev, int reg, uint32_t val);
    8992
    9093void pci_bus_scan(device_t *parent, int bus_num);
Note: See TracChangeset for help on using the changeset viewer.