Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/pciintel/pci.c

    rebcb05a r91579d5  
    4848
    4949#include <ddf/driver.h>
    50 #include <ddf/log.h>
    5150#include <devman.h>
    5251#include <ipc/devman.h>
    5352#include <ipc/dev_iface.h>
     53#include <ipc/irc.h>
     54#include <ipc/ns.h>
     55#include <ipc/services.h>
     56#include <sysinfo.h>
    5457#include <ops/hw_res.h>
    5558#include <device/hw_res.h>
    5659#include <ddi.h>
    5760#include <libarch/ddi.h>
     61#include <pci_dev_iface.h>
    5862
    5963#include "pci.h"
     
    8488static bool pciintel_enable_interrupt(ddf_fun_t *fnode)
    8589{
    86         /* TODO */
    87        
    88         return false;
     90        /* This is an old ugly way, copied from ne2000 driver */
     91        assert(fnode);
     92        pci_fun_t *dev_data = (pci_fun_t *) fnode->driver_data;
     93
     94        sysarg_t apic;
     95        sysarg_t i8259;
     96
     97        int irc_phone = -1;
     98        int irc_service = -1;
     99
     100        if ((sysinfo_get_value("apic", &apic) == EOK) && (apic)) {
     101                irc_service = SERVICE_APIC;
     102        } else if ((sysinfo_get_value("i8259", &i8259) == EOK) && (i8259)) {
     103                irc_service = SERVICE_I8259;
     104        }
     105
     106        if (irc_service == -1) {
     107                return false;
     108        }
     109
     110        irc_phone = service_connect_blocking(irc_service, 0, 0);
     111        if (irc_phone < 0) {
     112                return false;
     113        }
     114
     115        size_t i;
     116        for (i = 0; i < dev_data->hw_resources.count; i++) {
     117                if (dev_data->hw_resources.resources[i].type == INTERRUPT) {
     118                        int irq = dev_data->hw_resources.resources[i].res.interrupt.irq;
     119                        int rc = async_req_1_0(irc_phone, IRC_ENABLE_INTERRUPT, irq);
     120                        if (rc != EOK) {
     121                                async_hangup(irc_phone);
     122                                return false;
     123                        }
     124                }
     125        }
     126
     127        async_hangup(irc_phone);
     128        return true;
     129}
     130
     131static int pci_config_space_write_32(
     132    ddf_fun_t *fun, uint32_t address, uint32_t data)
     133{
     134        if (address > 252)
     135                return EINVAL;
     136        pci_conf_write_32(PCI_FUN(fun), address, data);
     137        return EOK;
     138}
     139
     140static int pci_config_space_write_16(
     141    ddf_fun_t *fun, uint32_t address, uint16_t data)
     142{
     143        if (address > 254)
     144                return EINVAL;
     145        pci_conf_write_16(PCI_FUN(fun), address, data);
     146        return EOK;
     147}
     148
     149static int pci_config_space_write_8(
     150    ddf_fun_t *fun, uint32_t address, uint8_t data)
     151{
     152        if (address > 255)
     153                return EINVAL;
     154        pci_conf_write_8(PCI_FUN(fun), address, data);
     155        return EOK;
     156}
     157
     158static int pci_config_space_read_32(
     159    ddf_fun_t *fun, uint32_t address, uint32_t *data)
     160{
     161        if (address > 252)
     162                return EINVAL;
     163        *data = pci_conf_read_32(PCI_FUN(fun), address);
     164        return EOK;
     165}
     166
     167static int pci_config_space_read_16(
     168    ddf_fun_t *fun, uint32_t address, uint16_t *data)
     169{
     170        if (address > 254)
     171                return EINVAL;
     172        *data = pci_conf_read_16(PCI_FUN(fun), address);
     173        return EOK;
     174}
     175
     176static int pci_config_space_read_8(
     177    ddf_fun_t *fun, uint32_t address, uint8_t *data)
     178{
     179        if (address > 255)
     180                return EINVAL;
     181        *data = pci_conf_read_8(PCI_FUN(fun), address);
     182        return EOK;
    89183}
    90184
     
    94188};
    95189
    96 static ddf_dev_ops_t pci_fun_ops;
     190static pci_dev_iface_t pci_dev_ops = {
     191        .config_space_read_8 = &pci_config_space_read_8,
     192        .config_space_read_16 = &pci_config_space_read_16,
     193        .config_space_read_32 = &pci_config_space_read_32,
     194        .config_space_write_8 = &pci_config_space_write_8,
     195        .config_space_write_16 = &pci_config_space_write_16,
     196        .config_space_write_32 = &pci_config_space_write_32
     197};
     198
     199static ddf_dev_ops_t pci_fun_ops = {
     200        .interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops,
     201        .interfaces[PCI_DEV_IFACE] = &pci_dev_ops
     202};
    97203
    98204static int pci_add_device(ddf_dev_t *);
     
    226332
    227333        if (match_id_str == NULL) {
    228                 ddf_msg(LVL_ERROR, "Out of memory creating match ID.");
     334                printf(NAME ": out of memory creating match ID.\n");
    229335                return;
    230336        }
     
    232338        rc = ddf_fun_add_match_id(fun->fnode, match_id_str, 90);
    233339        if (rc != EOK) {
    234                 ddf_msg(LVL_ERROR, "Failed adding match ID: %s",
     340                printf(NAME ": error adding match ID: %s\n",
    235341                    str_error(rc));
    236342        }
     
    288394        /* Get the value of the BAR. */
    289395        val = pci_conf_read_32(fun, addr);
     396
     397#define IO_MASK  (~0x3)
     398#define MEM_MASK (~0xf)
    290399       
    291400        io = (bool) (val & 1);
    292401        if (io) {
    293402                addrw64 = false;
     403                mask = IO_MASK;
    294404        } else {
     405                mask = MEM_MASK;
    295406                switch ((val >> 1) & 3) {
    296407                case 0:
     
    308419        /* Get the address mask. */
    309420        pci_conf_write_32(fun, addr, 0xffffffff);
    310         mask = pci_conf_read_32(fun, addr);
     421        mask &= pci_conf_read_32(fun, addr);
    311422       
    312423        /* Restore the original value. */
     
    324435       
    325436        if (range_addr != 0) {
    326                 ddf_msg(LVL_DEBUG, "Function %s : address = %" PRIx64
    327                     ", size = %x", fun->fnode->name, range_addr,
    328                     (unsigned int) range_size);
     437                printf(NAME ": function %s : ", fun->fnode->name);
     438                printf("address = %" PRIx64, range_addr);
     439                printf(", size = %x\n", (unsigned int) range_size);
    329440        }
    330441       
     
    351462        hw_res_list->count++;
    352463       
    353         ddf_msg(LVL_NOTE, "Function %s uses irq %x.", fun->fnode->name, irq);
     464        printf(NAME ": function %s uses irq %x.\n", fun->fnode->name, irq);
    354465}
    355466
     
    407518                        char *fun_name = pci_fun_create_name(fun);
    408519                        if (fun_name == NULL) {
    409                                 ddf_msg(LVL_ERROR, "Out of memory.");
     520                                printf(NAME ": out of memory.\n");
    410521                                return;
    411522                        }
     
    413524                        fnode = ddf_fun_create(bus->dnode, fun_inner, fun_name);
    414525                        if (fnode == NULL) {
    415                                 ddf_msg(LVL_ERROR, "Failed creating function.");
     526                                printf(NAME ": error creating function.\n");
    416527                                return;
    417528                        }
     
    427538                        fnode->driver_data = fun;
    428539                       
    429                         ddf_msg(LVL_DEBUG, "Adding new function %s.",
     540                        printf(NAME ": adding new function %s.\n",
    430541                            fnode->name);
    431542                       
     
    444555                                child_bus = pci_conf_read_8(fun,
    445556                                    PCI_BRIDGE_SEC_BUS_NUM);
    446                                 ddf_msg(LVL_DEBUG, "Device is pci-to-pci "
    447                                     "bridge, secondary bus number = %d.",
    448                                     bus_num);
     557                                printf(NAME ": device is pci-to-pci bridge, "
     558                                    "secondary bus number = %d.\n", bus_num);
    449559                                if (child_bus > bus_num)
    450560                                        pci_bus_scan(bus, child_bus);
     
    468578        int rc;
    469579       
    470         ddf_msg(LVL_DEBUG, "pci_add_device");
     580        printf(NAME ": pci_add_device\n");
    471581        dnode->parent_phone = -1;
    472582       
    473583        bus = pci_bus_new();
    474584        if (bus == NULL) {
    475                 ddf_msg(LVL_ERROR, "pci_add_device allocation failed.");
     585                printf(NAME ": pci_add_device allocation failed.\n");
    476586                rc = ENOMEM;
    477587                goto fail;
     
    483593            IPC_FLAG_BLOCKING);
    484594        if (dnode->parent_phone < 0) {
    485                 ddf_msg(LVL_ERROR, "pci_add_device failed to connect to the "
    486                     "parent's driver.");
     595                printf(NAME ": pci_add_device failed to connect to the "
     596                    "parent's driver.\n");
    487597                rc = dnode->parent_phone;
    488598                goto fail;
     
    493603        rc = hw_res_get_resource_list(dnode->parent_phone, &hw_resources);
    494604        if (rc != EOK) {
    495                 ddf_msg(LVL_ERROR, "pci_add_device failed to get hw resources "
    496                     "for the device.");
     605                printf(NAME ": pci_add_device failed to get hw resources for "
     606                    "the device.\n");
    497607                goto fail;
    498608        }
    499609        got_res = true;
    500610       
    501         ddf_msg(LVL_DEBUG, "conf_addr = %" PRIx64 ".",
     611        printf(NAME ": conf_addr = %" PRIx64 ".\n",
    502612            hw_resources.resources[0].res.io_range.address);
    503613       
     
    511621        if (pio_enable((void *)(uintptr_t)bus->conf_io_addr, 8,
    512622            &bus->conf_addr_port)) {
    513                 ddf_msg(LVL_ERROR, "Failed to enable configuration ports.");
     623                printf(NAME ": failed to enable configuration ports.\n");
    514624                rc = EADDRNOTAVAIL;
    515625                goto fail;
     
    518628       
    519629        /* Make the bus device more visible. It has no use yet. */
    520         ddf_msg(LVL_DEBUG, "Adding a 'ctl' function");
     630        printf(NAME ": adding a 'ctl' function\n");
    521631       
    522632        ctl = ddf_fun_create(bus->dnode, fun_exposed, "ctl");
    523633        if (ctl == NULL) {
    524                 ddf_msg(LVL_ERROR, "Failed creating control function.");
     634                printf(NAME ": error creating control function.\n");
    525635                rc = ENOMEM;
    526636                goto fail;
     
    529639        rc = ddf_fun_bind(ctl);
    530640        if (rc != EOK) {
    531                 ddf_msg(LVL_ERROR, "Failed binding control function.");
     641                printf(NAME ": error binding control function.\n");
    532642                goto fail;
    533643        }
    534644       
    535645        /* Enumerate functions. */
    536         ddf_msg(LVL_DEBUG, "Scanning the bus");
     646        printf(NAME ": scanning the bus\n");
    537647        pci_bus_scan(bus, 0);
    538648       
     
    556666static void pciintel_init(void)
    557667{
    558         ddf_log_init(NAME, LVL_ERROR);
    559668        pci_fun_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops;
     669        pci_fun_ops.interfaces[PCI_DEV_IFACE] = &pci_dev_ops;
    560670}
    561671
     
    629739size_t pci_bar_mask_to_size(uint32_t mask)
    630740{
    631         return ((mask & 0xfffffff0) ^ 0xffffffff) + 1;
     741        size_t size = mask & ~(mask - 1);
     742        return size;
    632743}
    633744
    634745int main(int argc, char *argv[])
    635746{
    636         printf(NAME ": HelenOS PCI bus driver (Intel method 1).\n");
     747        printf(NAME ": HelenOS pci bus driver (intel method 1).\n");
    637748        pciintel_init();
    638749        return ddf_driver_main(&pci_driver);
Note: See TracChangeset for help on using the changeset viewer.