acpi_status
acpi_os_read_pci_configuration (
    acpi_pci_id             *pci_id,
    u32                     reg,
    void                    *value,
    u32                     width)
{
    int			result = 0;
    if (!value)
        return AE_ERROR;

    switch (width)
    {
    case 8:
        result = pci_config_read(pci_id->segment, pci_id->bus,
                                 pci_id->device, pci_id->function, reg, 1, value);
        break;
    case 16:
        result = pci_config_read(pci_id->segment, pci_id->bus,
                                 pci_id->device, pci_id->function, reg, 2, value);
        break;
    case 32:
        result = pci_config_read(pci_id->segment, pci_id->bus,
                                 pci_id->device, pci_id->function, reg, 4, value);
        break;
    default:
        BUG();
    }

    return (result ? AE_ERROR : AE_OK);
}
Ejemplo n.º 2
0
/**
 * \brief Initialize the PCI root complex driver.
 */
void
pci_root_complex_init(void)
{
  uint32_t rcba_addr;
  pci_config_addr_t pci = { .raw = 0 };
  pci.dev = 31;
  pci.reg_off = 0xF0; /* Root Complex Base Address Register */

  /* masked to clear non-address bits. */
  rcba_addr = pci_config_read(pci) & ~0x3FFF;

  PROT_DOMAINS_INIT_ID(root_complex_drv);
  prot_domains_reg(&root_complex_drv, rcba_addr, 0x4000, 0, 0, false);
  SYSCALLS_INIT(pci_irq_agent_set_pirq);
  SYSCALLS_AUTHZ(pci_irq_agent_set_pirq, root_complex_drv);
}
/*---------------------------------------------------------------------------*/
/**
 * \brief Prevent further invocations of pci_irq_agent_set_pirq.
 */
void
pci_root_complex_lock(void)
{
  SYSCALLS_DEAUTHZ(pci_irq_agent_set_pirq, root_complex_drv);
}
Ejemplo n.º 3
0
void smm_init(void)
{
    uint32_t adr;
    uint32_t smi_en;
    unsigned if_backup;

    if_backup = cli();

    
    /*
    adr = (1<<31) | (LPC_BUS << 16)  |  (LPC_DEVICE << 11)  |  (LPC_FUNC <<  8)  |  LPC_OFFSET;
    outportl(CONFIG_ADDRESS, adr);
    pmbase = inportl(CONFIG_DATA);
    */
    pmbase = pci_config_read(LPC_BUS, LPC_DEVICE, LPC_FUNC, LPC_OFFSET);
    pmbase &= 0xFF80;
    IFV printf("SMM: located pmbase : 0x%x \n", pmbase);



    if (pmbase != 0) {

        adr = pmbase+0x30;                          /* SMI_EN I/O register is at pmbase+0x30 */

        /* read SMI_EN and display */
        smi_en = inportl(adr);
        bak_smi_en = smi_en;
        IFVV printf("SMI_EN: 0x%x \n", smi_en);
    }

    if (if_backup) sti();
}
Ejemplo n.º 4
0
Archivo: pci.c Proyecto: nwg/nanos
void pci_config_write_partial(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset, uint32_t value, int size) {
    int remainder = offset & 3;
    offset &= (~(uint8_t)3);
    uint32_t current = pci_config_read(bus, device, function, offset);
    value <<= remainder;
    current |= value;
    pci_config_write(bus, device, function, offset, value);
}
Ejemplo n.º 5
0
Archivo: pci.c Proyecto: nwg/nanos
uint32_t pci_config_read_partial(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset, int size) {
    int remainder = offset & 3;
    offset &= (~(uint8_t)3);
    uint32_t value = pci_config_read(bus, device, function, offset);
    value >>= remainder;
    value &= ( (1 << size) - 1 );
    return value;
}
Ejemplo n.º 6
0
/**
 * \brief       Enable PCI command bits of the specified PCI configuration
 *              register.
 * \param addr  Address of PCI configuration register.
 * \param flags Flags used to enable PCI command bits.
 */
void
pci_command_enable(pci_config_addr_t addr, uint32_t flags)
{
  uint32_t data;

  addr.reg_off = 0x04; /* PCI COMMAND_REGISTER */

  data = pci_config_read(addr);
  pci_config_write(addr, data | flags);
}
Ejemplo n.º 7
0
/**
 * \brief          Initialize a structure for a PCI device driver that performs
 *                 MMIO to address range 0.  Assumes that device has already
 *                 been configured with an MMIO address range 0, e.g. by
 *                 firmware.
 * \param c_this   Structure that will be initialized to represent the driver.
 * \param pci_addr PCI base address of device.
 * \param mmio_sz  Size of MMIO region.
 * \param meta     Base address of optional driver-defined metadata.
 * \param meta_sz  Size of optional driver-defined metadata.
 */
void
pci_init(pci_driver_t ATTR_KERN_ADDR_SPACE *c_this,
         pci_config_addr_t pci_addr,
         size_t mmio_sz,
         uintptr_t meta,
         size_t meta_sz)
{
  uintptr_t mmio;

  /* The BAR value is masked to clear non-address bits. */
  mmio = pci_config_read(pci_addr) & ~0xFFF;

  prot_domains_reg(c_this, mmio, mmio_sz, meta, meta_sz, false);
}
Ejemplo n.º 8
0
/**
 * \brief                 Set current IRQ to PIRQ. The interrupt router can be
 *                        programmed to allow PIRQ[A:H] to be routed internally
 *                        to the 8259 as ISA compatible interrupts. See also
 *                        pci_irq_agent_set_pirq().
 * \param pirq            PIRQ to be used, PIRQ[A:H].
 * \param pin             IRQ to be used, IRQ[0:15].
 * \param route_to_legacy Whether or not the interrupt should be routed to PIC 8259.
 */
void
pci_pirq_set_irq(PIRQ pirq, uint8_t irq, uint8_t route_to_legacy)
{
  pci_config_addr_t pci;
  uint32_t value;

  assert(pirq >= PIRQA && pirq <= PIRQH);
  assert(irq >= 0 && irq <= 0xF);
  assert(route_to_legacy == 0 || route_to_legacy == 1);

  pci.raw = 0;
  pci.bus = 0;
  pci.dev = 31;
  pci.func = 0;
  pci.reg_off = (pirq <= PIRQD) ? 0x60 : 0x64; /* PABCDRC and PEFGHRC Registers */

  value = pci_config_read(pci);

  switch(pirq) {
  case PIRQA:
  case PIRQE:
    value &= ~0x8F;
    value |= irq;
    value |= (!route_to_legacy << 7);
    break;
  case PIRQB:
  case PIRQF:
    value &= ~0x8F00;
    value |= (irq << 8);
    value |= (!route_to_legacy << 15);
    break;
  case PIRQC:
  case PIRQG:
    value &= ~0x8F0000;
    value |= (irq << 16);
    value |= (!route_to_legacy << 23);
    break;
  case PIRQD:
  case PIRQH:
    value &= ~0x8F000000;
    value |= (irq << 24);
    value |= (!route_to_legacy << 31);
  }

  set_addr(pci);
  outl(PCI_CONFIG_DATA_PORT, value);
}
Ejemplo n.º 9
0
int rtl8139_init(unsigned bus, unsigned slot)
{
    uint16_t iobase;
    iobase = pci_config_read(bus, slot, 0, 0x10);
    if (iobase & 1) {
        // io-port: ignore 2 least significant bits
        iobase &= ~0x03;
    }
    IFV printf("rtl8139: iobase = 0x%x\n", iobase);

    uint8_t mac[6];
    unsigned u;
    for (u=0; u<6; u++) {
        mac[u] = inportb(iobase + u);
    }
    IFV printf("rtl8139: mac = %x:%x:%x:%x:%x:%x\n",
               mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);

    return 1;  // the driver was not loaded, so far, we just print some information
}
Ejemplo n.º 10
0
/*  ----------------------------------------------------
 *  Function:       pci_dev_get_info
 *  --------------------------------------------------*/
pci_dev_t * pci_dev_get_info(uint8_t bus, uint8_t slot, uint8_t func){

    uint32_t tmp    = pci_config_read(bus, slot, func, 0);

    if((tmp & 0xFFFF) == 0xFFFF){
        return NULL; // Vendor ID of 0xFFFF signifies non-existent device.
    }

    pci_dev_t *dev  = (pci_dev_t *) kmalloc(sizeof(pci_dev_t));
    MALLOC_PANIC(dev);

    dev->dev_id          = tmp >> 16;
    dev->vendor_id       = tmp & 0xFFFF;

    tmp                  = pci_config_read(bus, slot, func, 2);
    dev->class_id        = tmp >> 24;
    dev->subclass_id     = tmp >> 16 & 0xFF;
    dev->prog_if         = tmp >> 8 & 0xFF;
    dev->revision_id     = tmp & 0xFF;

    tmp                  = pci_config_read(bus, slot, func, 3);
    dev->bist            = tmp >> 24;
    dev->header_type     = tmp >> 16 & 0x7F; // Bit 7 is the multi function flag.
                                             // We don't use it
    dev->latency         = tmp >> 8 & 0xFF;
    dev->cache_line_size = tmp & 0x0FF;

    dev->bar0            = pci_config_read(bus, slot, func, 4);
    dev->bar1            = pci_config_read(bus, slot, func, 5);

    // The contents of the rest of the PCI device header depends on
    // the header type.
    // 0x00 - standard header.
    // 0x01 - PCI-PCI bridge header.
    // 0x02 - Card bus bridge header.
    //
    switch(dev->header_type){
        case 0x00:
            dev->bar2            = pci_config_read(bus, slot, func, 6);
            dev->bar3            = pci_config_read(bus, slot, func, 7);
            dev->bar4            = pci_config_read(bus, slot, func, 8);
            dev->bar5            = pci_config_read(bus, slot, func, 9);

            tmp                  = pci_config_read(bus, slot, func, 11);
            dev->subsys_id       = tmp >> 16;
            dev->subsys_vendor_id= tmp & 0xFFFF;

            tmp                  = pci_config_read(bus, slot, func, 15);
            dev->int_pin         = (tmp >> 8) & 0xFF;
            dev->int_line        = tmp & 0xFF;
            break;
        case 0x01:
            break;

        default:
            break;
    }


    dev->bus             = bus;
    dev->slot            = slot;
    dev->func            = func;

    pci_dev_lookup_ids(dev);

    return dev;
}