xref: /kvmtool/powerpc/spapr_pci.h (revision c481cfd579e5039b5ed6443c4905a43e53fd91aa)
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