Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 274233
b: refs/heads/master
c: 2bcd1c0
h: refs/heads/master
i:
  274231: 4dfd044
v: v3
  • Loading branch information
Timur Tabi authored and Kumar Gala committed Oct 14, 2011
1 parent ee365e5 commit 2ce4886
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 9 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 45116806139743cf35baa01a584e5972e5d833f6
refs/heads/master: 2bcd1c0cfcf53a384159c272c972645e7e822140
42 changes: 42 additions & 0 deletions trunk/Documentation/devicetree/bindings/powerpc/fsl/msi-pic.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,16 @@ Required properties:
are routed to IPIC, and for 85xx/86xx cpu the interrupts are routed
to MPIC.

Optional properties:
- msi-address-64: 64-bit PCI address of the MSIIR register. The MSIIR register
is used for MSI messaging. The address of MSIIR in PCI address space is
the MSI message address.

This property may be used in virtualized environments where the hypervisor
has created an alternate mapping for the MSIR block. See below for an
explanation.


Example:
msi@41600 {
compatible = "fsl,mpc8610-msi", "fsl,mpic-msi";
Expand All @@ -41,3 +51,35 @@ Example:
0xe7 0>;
interrupt-parent = <&mpic>;
};

The Freescale hypervisor and msi-address-64
-------------------------------------------
Normally, PCI devices have access to all of CCSR via an ATMU mapping. The
Freescale MSI driver calculates the address of MSIIR (in the MSI register
block) and sets that address as the MSI message address.

In a virtualized environment, the hypervisor may need to create an IOMMU
mapping for MSIIR. The Freescale ePAPR hypervisor has this requirement
because of hardware limitations of the Peripheral Access Management Unit
(PAMU), which is currently the only IOMMU that the hypervisor supports.
The ATMU is programmed with the guest physical address, and the PAMU
intercepts transactions and reroutes them to the true physical address.

In the PAMU, each PCI controller is given only one primary window. The
PAMU restricts DMA operations so that they can only occur within a window.
Because PCI devices must be able to DMA to memory, the primary window must
be used to cover all of the guest's memory space.

PAMU primary windows can be divided into 256 subwindows, and each
subwindow can have its own address mapping ("guest physical" to "true
physical"). However, each subwindow has to have the same alignment, which
means they cannot be located at just any address. Because of these
restrictions, it is usually impossible to create a 4KB subwindow that
covers MSIIR where it's normally located.

Therefore, the hypervisor has to create a subwindow inside the same
primary window used for memory, but mapped to the MSIR block (where MSIIR
lives). The first subwindow after the end of guest memory is used for
this. The address specified in the msi-address-64 property is the PCI
address of MSIIR. The hypervisor configures the PAMU to map that address to
the true physical address of MSIIR.
20 changes: 14 additions & 6 deletions trunk/arch/powerpc/sysdev/fsl_msi.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ LIST_HEAD(msi_head);

struct fsl_msi_feature {
u32 fsl_pic_ip;
u32 msiir_offset;
u32 msiir_offset; /* Offset of MSIIR, relative to start of MSIR bank */
};

struct fsl_msi_cascade_data {
Expand Down Expand Up @@ -126,10 +126,19 @@ static void fsl_compose_msi_msg(struct pci_dev *pdev, int hwirq,
{
struct fsl_msi *msi_data = fsl_msi_data;
struct pci_controller *hose = pci_bus_to_host(pdev->bus);
u64 base = fsl_pci_immrbar_base(hose);
u64 address; /* Physical address of the MSIIR */
int len;
const u64 *reg;

/* If the msi-address-64 property exists, then use it */
reg = of_get_property(hose->dn, "msi-address-64", &len);
if (reg && (len == sizeof(u64)))
address = be64_to_cpup(reg);
else
address = fsl_pci_immrbar_base(hose) + msi_data->msiir_offset;

msg->address_lo = msi_data->msi_addr_lo + lower_32_bits(base);
msg->address_hi = msi_data->msi_addr_hi + upper_32_bits(base);
msg->address_lo = lower_32_bits(address);
msg->address_hi = upper_32_bits(address);

msg->data = hwirq;

Expand Down Expand Up @@ -359,8 +368,7 @@ static int __devinit fsl_of_msi_probe(struct platform_device *dev)

msi->irqhost->host_data = msi;

msi->msi_addr_hi = 0x0;
msi->msi_addr_lo = features->msiir_offset + (res.start & 0xfffff);
msi->msiir_offset = features->msiir_offset + (res.start & 0xfffff);

rc = fsl_msi_init_allocator(msi);
if (rc) {
Expand Down
3 changes: 1 addition & 2 deletions trunk/arch/powerpc/sysdev/fsl_msi.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ struct fsl_msi {

unsigned long cascade_irq;

u32 msi_addr_lo;
u32 msi_addr_hi;
u32 msiir_offset; /* Offset of MSIIR, relative to start of CCSR */
void __iomem *msi_regs;
u32 feature;
int msi_virqs[NR_MSI_REG];
Expand Down

0 comments on commit 2ce4886

Please sign in to comment.