1c481cfd5SMatt Evans /* 2c481cfd5SMatt Evans * SPAPR PHB definitions 3c481cfd5SMatt Evans * 4c481cfd5SMatt Evans * Modifications by Matt Evans <matt@ozlabs.org>, IBM Corporation. 5c481cfd5SMatt Evans * 6c481cfd5SMatt Evans * This program is free software; you can redistribute it and/or modify it 7c481cfd5SMatt Evans * under the terms of the GNU General Public License version 2 as published 8c481cfd5SMatt Evans * by the Free Software Foundation. 9c481cfd5SMatt Evans */ 10c481cfd5SMatt Evans 11c481cfd5SMatt Evans #ifndef SPAPR_PCI_H 12c481cfd5SMatt Evans #define SPAPR_PCI_H 13c481cfd5SMatt Evans 14c481cfd5SMatt Evans #include "kvm/kvm.h" 15c481cfd5SMatt Evans #include "spapr.h" 16c481cfd5SMatt Evans #include <inttypes.h> 17c481cfd5SMatt Evans 18c481cfd5SMatt Evans /* With XICS, we can easily accomodate 1 IRQ per PCI device. */ 19c481cfd5SMatt Evans 20c481cfd5SMatt Evans #define SPAPR_PCI_NUM_LSI 256 21c481cfd5SMatt Evans 22c481cfd5SMatt Evans struct spapr_phb { 23c481cfd5SMatt Evans uint64_t buid; 24c481cfd5SMatt Evans uint64_t mem_addr; 25c481cfd5SMatt Evans uint64_t mem_size; 26c481cfd5SMatt Evans uint64_t io_addr; 27c481cfd5SMatt Evans uint64_t io_size; 28c481cfd5SMatt Evans }; 29c481cfd5SMatt Evans 30c481cfd5SMatt Evans void spapr_create_phb(struct kvm *kvm, 31c481cfd5SMatt Evans const char *busname, uint64_t buid, 32c481cfd5SMatt Evans uint64_t mem_win_addr, uint64_t mem_win_size, 33c481cfd5SMatt Evans uint64_t io_win_addr, uint64_t io_win_size); 34c481cfd5SMatt Evans 35c481cfd5SMatt Evans int spapr_populate_pci_devices(struct kvm *kvm, 36c481cfd5SMatt Evans uint32_t xics_phandle, 37c481cfd5SMatt Evans void *fdt); 38c481cfd5SMatt Evans 39*9b735910SMarc Zyngier static inline bool spapr_phb_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8 *data, u32 len, u8 is_write) 40c481cfd5SMatt Evans { 41c481cfd5SMatt Evans if ((phys_addr >= SPAPR_PCI_IO_WIN_ADDR) && 42c481cfd5SMatt Evans (phys_addr < SPAPR_PCI_IO_WIN_ADDR + 43c481cfd5SMatt Evans SPAPR_PCI_IO_WIN_SIZE)) { 44*9b735910SMarc Zyngier return kvm__emulate_io(vcpu->kvm, phys_addr - SPAPR_PCI_IO_WIN_ADDR, 45c481cfd5SMatt Evans data, is_write ? KVM_EXIT_IO_OUT : 46c481cfd5SMatt Evans KVM_EXIT_IO_IN, 47c481cfd5SMatt Evans len, 1); 48c481cfd5SMatt Evans } else if ((phys_addr >= SPAPR_PCI_MEM_WIN_ADDR) && 49c481cfd5SMatt Evans (phys_addr < SPAPR_PCI_MEM_WIN_ADDR + 50c481cfd5SMatt Evans SPAPR_PCI_MEM_WIN_SIZE)) { 51*9b735910SMarc Zyngier return kvm__emulate_mmio(vcpu, phys_addr - SPAPR_PCI_MEM_WIN_ADDR, 52c481cfd5SMatt Evans data, len, is_write); 53c481cfd5SMatt Evans } 54c481cfd5SMatt Evans return false; 55c481cfd5SMatt Evans } 56c481cfd5SMatt Evans 57c481cfd5SMatt Evans #endif 58