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