static pcibus_t pci_bar_address(PCIDevice *d,

				int reg, uint8_t type, pcibus_t size)

{

    pcibus_t new_addr, last_addr;

    int bar = pci_bar(d, reg);

    uint16_t cmd = pci_get_word(d->config + PCI_COMMAND);



    if (type & PCI_BASE_ADDRESS_SPACE_IO) {

        if (!(cmd & PCI_COMMAND_IO)) {

            return PCI_BAR_UNMAPPED;

        }

        new_addr = pci_get_long(d->config + bar) & ~(size - 1);

        last_addr = new_addr + size - 1;

        /* Check if 32 bit BAR wraps around explicitly.

         * TODO: make priorities correct and remove this work around.

         */

        if (last_addr <= new_addr || new_addr == 0 || last_addr >= UINT32_MAX) {

            return PCI_BAR_UNMAPPED;

        }

        return new_addr;

    }



    if (!(cmd & PCI_COMMAND_MEMORY)) {

        return PCI_BAR_UNMAPPED;

    }

    if (type & PCI_BASE_ADDRESS_MEM_TYPE_64) {

        new_addr = pci_get_quad(d->config + bar);

    } else {

        new_addr = pci_get_long(d->config + bar);

    }

    /* the ROM slot has a specific enable bit */

    if (reg == PCI_ROM_SLOT && !(new_addr & PCI_ROM_ADDRESS_ENABLE)) {

        return PCI_BAR_UNMAPPED;

    }

    new_addr &= ~(size - 1);

    last_addr = new_addr + size - 1;

    /* NOTE: we do not support wrapping */

    /* XXX: as we cannot support really dynamic

       mappings, we handle specific values as invalid

       mappings. */

    if (last_addr <= new_addr || new_addr == 0 ||

        last_addr == PCI_BAR_UNMAPPED) {

        return PCI_BAR_UNMAPPED;

    }



    /* Now pcibus_t is 64bit.

     * Check if 32 bit BAR wraps around explicitly.

     * Without this, PC ide doesn't work well.

     * TODO: remove this work around.

     */

    if  (!(type & PCI_BASE_ADDRESS_MEM_TYPE_64) && last_addr >= UINT32_MAX) {

        return PCI_BAR_UNMAPPED;

    }



    /*

     * OS is allowed to set BAR beyond its addressable

     * bits. For example, 32 bit OS can set 64bit bar

     * to >4G. Check it. TODO: we might need to support

     * it in the future for e.g. PAE.

     */

    if (last_addr >= HWADDR_MAX) {

        return PCI_BAR_UNMAPPED;

    }



    return new_addr;

}

static pcibus_t pci_bar_address(PCIDevice *d,

				int reg, uint8_t type, pcibus_t size)

{

    pcibus_t new_addr, last_addr;

    int bar = pci_bar(d, reg);

    uint16_t cmd = pci_get_word(d->config + PCI_COMMAND);



    if (type & PCI_BASE_ADDRESS_SPACE_IO) {

        if (!(cmd & PCI_COMMAND_IO)) {

            return PCI_BAR_UNMAPPED;

        }

        new_addr = pci_get_long(d->config + bar) & ~(size - 1);

        last_addr = new_addr + size - 1;

        





        if (last_addr <= new_addr || new_addr == 0 || last_addr >= UINT32_MAX) {

            return PCI_BAR_UNMAPPED;

        }

        return new_addr;

    }



    if (!(cmd & PCI_COMMAND_MEMORY)) {

        return PCI_BAR_UNMAPPED;

    }

    if (type & PCI_BASE_ADDRESS_MEM_TYPE_64) {

        new_addr = pci_get_quad(d->config + bar);

    } else {

        new_addr = pci_get_long(d->config + bar);

    }

    

    if (reg == PCI_ROM_SLOT && !(new_addr & PCI_ROM_ADDRESS_ENABLE)) {

        return PCI_BAR_UNMAPPED;

    }

    new_addr &= ~(size - 1);

    last_addr = new_addr + size - 1;

    

    





    if (last_addr <= new_addr || new_addr == 0 ||

        last_addr == PCI_BAR_UNMAPPED) {

        return PCI_BAR_UNMAPPED;

    }



    









    if  (!(type & PCI_BASE_ADDRESS_MEM_TYPE_64) && last_addr >= UINT32_MAX) {

        return PCI_BAR_UNMAPPED;

    }



    











    if (last_addr >= HWADDR_MAX) {

        return PCI_BAR_UNMAPPED;

    }



    return new_addr;

}

static pcibus_t FUNC_0(PCIDevice *d,

				int reg, uint8_t type, pcibus_t size)

{

    pcibus_t new_addr, last_addr;

    int VAR_0 = pci_bar(d, reg);

    uint16_t cmd = pci_get_word(d->config + PCI_COMMAND);



    if (type & PCI_BASE_ADDRESS_SPACE_IO) {

        if (!(cmd & PCI_COMMAND_IO)) {

            return PCI_BAR_UNMAPPED;

        }

        new_addr = pci_get_long(d->config + VAR_0) & ~(size - 1);

        last_addr = new_addr + size - 1;

        





        if (last_addr <= new_addr || new_addr == 0 || last_addr >= UINT32_MAX) {

            return PCI_BAR_UNMAPPED;

        }

        return new_addr;

    }



    if (!(cmd & PCI_COMMAND_MEMORY)) {

        return PCI_BAR_UNMAPPED;

    }

    if (type & PCI_BASE_ADDRESS_MEM_TYPE_64) {

        new_addr = pci_get_quad(d->config + VAR_0);

    } else {

        new_addr = pci_get_long(d->config + VAR_0);

    }

    

    if (reg == PCI_ROM_SLOT && !(new_addr & PCI_ROM_ADDRESS_ENABLE)) {

        return PCI_BAR_UNMAPPED;

    }

    new_addr &= ~(size - 1);

    last_addr = new_addr + size - 1;

    

    





    if (last_addr <= new_addr || new_addr == 0 ||

        last_addr == PCI_BAR_UNMAPPED) {

        return PCI_BAR_UNMAPPED;

    }



    









    if  (!(type & PCI_BASE_ADDRESS_MEM_TYPE_64) && last_addr >= UINT32_MAX) {

        return PCI_BAR_UNMAPPED;

    }



    











    if (last_addr >= HWADDR_MAX) {

        return PCI_BAR_UNMAPPED;

    }



    return new_addr;

}

static pcibus_t FUNC_0(PCIDevice *d,
int reg, uint8_t type, pcibus_t size)
{ pcibus_t new_addr, last_addr; int VAR_0 = pci_bar(d, reg); uint16_t cmd = pci_get_word(d->config + PCI_COMMAND); if (type & PCI_BASE_ADDRESS_SPACE_IO) { if (!(cmd & PCI_COMMAND_IO)) { return PCI_BAR_UNMAPPED; } new_addr = pci_get_long(d->config + VAR_0) & ~(size - 1); last_addr = new_addr + size - 1; if (last_addr <= new_addr || new_addr == 0 || last_addr >= UINT32_MAX) { return PCI_BAR_UNMAPPED; } return new_addr; } if (!(cmd & PCI_COMMAND_MEMORY)) { return PCI_BAR_UNMAPPED; } if (type & PCI_BASE_ADDRESS_MEM_TYPE_64) { new_addr = pci_get_quad(d->config + VAR_0); } else { new_addr = pci_get_long(d->config + VAR_0); } if (reg == PCI_ROM_SLOT && !(new_addr & PCI_ROM_ADDRESS_ENABLE)) { return PCI_BAR_UNMAPPED; } new_addr &= ~(size - 1); last_addr = new_addr + size - 1; if (last_addr <= new_addr || new_addr == 0 ||
last_addr == PCI_BAR_UNMAPPED) { return PCI_BAR_UNMAPPED; } if  (!(type & PCI_BASE_ADDRESS_MEM_TYPE_64) && last_addr >= UINT32_MAX) { return PCI_BAR_UNMAPPED; } if (last_addr >= HWADDR_MAX) { return PCI_BAR_UNMAPPED; } return new_addr; }