/** * NOTE: Depends on pci_read_cfg32 (architecture specific) * * This is architecture independant code expressed in terms of the architecture * specific pci_read_cfg32. In other words, to use this function, the target * architecture must have implemented pci_read_cfg32. For an example of this, * refer to x86/pci_read_cfg32.c. */ uint8_t pci_read_cfg8(uint8_t bus, uint8_t dev_number, uint8_t func_number, uint8_t reg_offset) { uint32_t temp; temp = pci_read_cfg32(bus, dev_number, func_number, (reg_offset & ~3)); temp >>= (8 * (reg_offset & 3)); return (uint8_t)(temp); }
/** * NOTE: Depends on pci_write_cfg32 (architecture specific) * * This is architecture independant code expressed in terms of the architecture * specific pci_read_cfg32. In other words, to use this function, the target * architecture must have implemented pci_write_cfg32. For an example of this, * refer to x86/pci_write_cfg32.c. */ void pci_write_cfg8(uint8_t bus, uint8_t dev_number, uint8_t func_number, uint8_t reg_offset, uint8_t value) { uint32_t temp; uint8_t shift = (8 * (reg_offset & 3)); temp = pci_read_cfg32(bus, dev_number, func_number, (reg_offset & ~3)); temp &= ~(0xff << shift); temp |= (((uint32_t)value) << shift); pci_write_cfg32(bus, dev_number, func_number, (reg_offset & ~3), temp); }
/** * NOTE: Depends on pci_write_cfg32 (architecture specific) * * This is architecture independant code expressed in terms of the architecture * specific pci_read_cfg32. In other words, to use this function, the target * architecture must have implemented pci_write_cfg32. For an example of this, * refer to x86/pci_write_cfg32.c. */ void pci_write_cfg16(uint8_t bus, uint8_t dev_number, uint8_t func_number, uint8_t reg_offset, uint16_t value) { uint32_t temp; uint8_t shift = (8 * (reg_offset & 3)); if (reg_offset & 1) { /** * We don't support unaligned 16bit writes. */ crash("Unaligned 16bit PCI write.\n"); } temp = pci_read_cfg32(bus, dev_number, func_number, (reg_offset & ~3)); temp &= ~(0xffff << shift); temp |= (((uint32_t)value) << shift); pci_write_cfg32(bus, dev_number, func_number, (reg_offset & ~3), temp); }