Re: [PATCH v2] powerpc: add real mode support for dma operations on powernv

2013-07-08 Thread Benjamin Herrenschmidt
On Mon, 2013-07-08 at 17:31 +1000, Alexey Kardashevskiy wrote:

> btw is phys_addr_t correct here?

Yes.

Cheers,
Ben.


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2] powerpc: add real mode support for dma operations on powernv

2013-07-08 Thread Alexey Kardashevskiy
On 07/08/2013 05:20 PM, Benjamin Herrenschmidt wrote:
> On Mon, 2013-07-08 at 14:44 +1000, Alexey Kardashevskiy wrote:
> 
>> diff --git a/arch/powerpc/platforms/powernv/pci.h 
>> b/arch/powerpc/platforms/powernv/pci.h
>> index 25d76c4..7ea82c1 100644
>> --- a/arch/powerpc/platforms/powernv/pci.h
>> +++ b/arch/powerpc/platforms/powernv/pci.h
>> @@ -52,6 +52,7 @@ struct pnv_ioda_pe {
>>  int tce32_seg;
>>  int tce32_segcount;
>>  struct iommu_table  tce32_table;
>> +phys_addr_t it_index_rm;
> 
> Please 
> 
> The fact that we hijack the it_index field of the iommu table
> for the virtual address is bad enough, but really don't need
> to perpetuate this :-)
> 
> Call the field something decent such as "tce_inval_reg_phys"


Yes we can. I just find it veeery attractive when I can grep "\http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2] powerpc: add real mode support for dma operations on powernv

2013-07-08 Thread Benjamin Herrenschmidt
On Mon, 2013-07-08 at 14:44 +1000, Alexey Kardashevskiy wrote:

> diff --git a/arch/powerpc/platforms/powernv/pci.h 
> b/arch/powerpc/platforms/powernv/pci.h
> index 25d76c4..7ea82c1 100644
> --- a/arch/powerpc/platforms/powernv/pci.h
> +++ b/arch/powerpc/platforms/powernv/pci.h
> @@ -52,6 +52,7 @@ struct pnv_ioda_pe {
>   int tce32_seg;
>   int tce32_segcount;
>   struct iommu_table  tce32_table;
> + phys_addr_t it_index_rm;

Please 

The fact that we hijack the it_index field of the iommu table
for the virtual address is bad enough, but really don't need
to perpetuate this :-)

Call the field something decent such as "tce_inval_reg_phys"

Cheers,
Ben.


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2] powerpc: add real mode support for dma operations on powernv

2013-07-08 Thread Benjamin Herrenschmidt
On Mon, 2013-07-08 at 14:44 +1000, Alexey Kardashevskiy wrote:

 diff --git a/arch/powerpc/platforms/powernv/pci.h 
 b/arch/powerpc/platforms/powernv/pci.h
 index 25d76c4..7ea82c1 100644
 --- a/arch/powerpc/platforms/powernv/pci.h
 +++ b/arch/powerpc/platforms/powernv/pci.h
 @@ -52,6 +52,7 @@ struct pnv_ioda_pe {
   int tce32_seg;
   int tce32_segcount;
   struct iommu_table  tce32_table;
 + phys_addr_t it_index_rm;

Please 

The fact that we hijack the it_index field of the iommu table
for the virtual address is bad enough, but really don't need
to perpetuate this :-)

Call the field something decent such as tce_inval_reg_phys

Cheers,
Ben.


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2] powerpc: add real mode support for dma operations on powernv

2013-07-08 Thread Alexey Kardashevskiy
On 07/08/2013 05:20 PM, Benjamin Herrenschmidt wrote:
 On Mon, 2013-07-08 at 14:44 +1000, Alexey Kardashevskiy wrote:
 
 diff --git a/arch/powerpc/platforms/powernv/pci.h 
 b/arch/powerpc/platforms/powernv/pci.h
 index 25d76c4..7ea82c1 100644
 --- a/arch/powerpc/platforms/powernv/pci.h
 +++ b/arch/powerpc/platforms/powernv/pci.h
 @@ -52,6 +52,7 @@ struct pnv_ioda_pe {
  int tce32_seg;
  int tce32_segcount;
  struct iommu_table  tce32_table;
 +phys_addr_t it_index_rm;
 
 Please 
 
 The fact that we hijack the it_index field of the iommu table
 for the virtual address is bad enough, but really don't need
 to perpetuate this :-)
 
 Call the field something decent such as tce_inval_reg_phys


Yes we can. I just find it veeery attractive when I can grep \it_
and get all users of iommu_table.

btw is phys_addr_t correct here?


-- 
Alexey
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2] powerpc: add real mode support for dma operations on powernv

2013-07-08 Thread Benjamin Herrenschmidt
On Mon, 2013-07-08 at 17:31 +1000, Alexey Kardashevskiy wrote:

 btw is phys_addr_t correct here?

Yes.

Cheers,
Ben.


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2] powerpc: add real mode support for dma operations on powernv

2013-07-07 Thread Alexey Kardashevskiy
The existing TCE machine calls (tce_build and tce_free) only support
virtual mode as they call __raw_writeq for TCE invalidation what
fails in real mode.

This introduces tce_build_rm and tce_free_rm real mode versions
which do mostly the same but use "Store Doubleword Caching Inhibited
Indexed" instruction for TCE invalidation.

This new feature is going to be utilized by real mode support of VFIO.

Signed-off-by: Alexey Kardashevskiy 
---
Changes:
2013/08/07:
* tested on p7ioc and fixed a bug with realmode addresses

Signed-off-by: Alexey Kardashevskiy 
---
 arch/powerpc/include/asm/machdep.h| 12 +
 arch/powerpc/platforms/powernv/pci-ioda.c | 43 ++-
 arch/powerpc/platforms/powernv/pci.c  | 38 ++-
 arch/powerpc/platforms/powernv/pci.h  |  3 ++-
 4 files changed, 77 insertions(+), 19 deletions(-)

diff --git a/arch/powerpc/include/asm/machdep.h 
b/arch/powerpc/include/asm/machdep.h
index 92386fc..0c19eef 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -75,6 +75,18 @@ struct machdep_calls {
long index);
void(*tce_flush)(struct iommu_table *tbl);
 
+   /* _rm versions are for real mode use only */
+   int (*tce_build_rm)(struct iommu_table *tbl,
+long index,
+long npages,
+unsigned long uaddr,
+enum dma_data_direction direction,
+struct dma_attrs *attrs);
+   void(*tce_free_rm)(struct iommu_table *tbl,
+   long index,
+   long npages);
+   void(*tce_flush_rm)(struct iommu_table *tbl);
+
void __iomem *  (*ioremap)(phys_addr_t addr, unsigned long size,
   unsigned long flags, void *caller);
void(*iounmap)(volatile void __iomem *token);
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index d200594..8a70003 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -68,6 +68,12 @@ define_pe_printk_level(pe_err, KERN_ERR);
 define_pe_printk_level(pe_warn, KERN_WARNING);
 define_pe_printk_level(pe_info, KERN_INFO);
 
+static inline void __raw_rm_writeq(u64 val, volatile void __iomem *paddr)
+{
+   __asm__ __volatile__("stdcix %0,0,%1"
+   : : "r" (val), "r" (paddr) : "memory");
+}
+
 static int pnv_ioda_alloc_pe(struct pnv_phb *phb)
 {
unsigned long pe;
@@ -452,10 +458,13 @@ static void pnv_ioda_setup_bus_dma(struct pnv_ioda_pe 
*pe, struct pci_bus *bus)
}
 }
 
-static void pnv_pci_ioda1_tce_invalidate(struct iommu_table *tbl,
-u64 *startp, u64 *endp)
+static void pnv_pci_ioda1_tce_invalidate(struct pnv_ioda_pe *pe,
+struct iommu_table *tbl,
+u64 *startp, u64 *endp, bool rm)
 {
-   u64 __iomem *invalidate = (u64 __iomem *)tbl->it_index;
+   u64 __iomem *invalidate = rm?
+   (u64 __iomem *)pe->it_index_rm:
+   (u64 __iomem *)tbl->it_index;
unsigned long start, end, inc;
 
start = __pa(startp);
@@ -482,7 +491,10 @@ static void pnv_pci_ioda1_tce_invalidate(struct 
iommu_table *tbl,
 
 mb(); /* Ensure above stores are visible */
 while (start <= end) {
-__raw_writeq(start, invalidate);
+   if (rm)
+   __raw_rm_writeq(start, invalidate);
+   else
+   __raw_writeq(start, invalidate);
 start += inc;
 }
 
@@ -494,10 +506,12 @@ static void pnv_pci_ioda1_tce_invalidate(struct 
iommu_table *tbl,
 
 static void pnv_pci_ioda2_tce_invalidate(struct pnv_ioda_pe *pe,
 struct iommu_table *tbl,
-u64 *startp, u64 *endp)
+u64 *startp, u64 *endp, bool rm)
 {
unsigned long start, end, inc;
-   u64 __iomem *invalidate = (u64 __iomem *)tbl->it_index;
+   u64 __iomem *invalidate = rm?
+   (u64 __iomem *)pe->it_index_rm:
+   (u64 __iomem *)tbl->it_index;
 
/* We'll invalidate DMA address in PE scope */
start = 0x2ul << 60;
@@ -513,22 +527,25 @@ static void pnv_pci_ioda2_tce_invalidate(struct 
pnv_ioda_pe *pe,
mb();
 
while (start <= end) {
-   __raw_writeq(start, invalidate);
+   if (rm)
+   __raw_rm_writeq(start, invalidate);
+   else
+   __raw_writeq(start, invalidate);
start += inc;
}
 }
 
 void 

[PATCH v2] powerpc: add real mode support for dma operations on powernv

2013-07-07 Thread Alexey Kardashevskiy
The existing TCE machine calls (tce_build and tce_free) only support
virtual mode as they call __raw_writeq for TCE invalidation what
fails in real mode.

This introduces tce_build_rm and tce_free_rm real mode versions
which do mostly the same but use Store Doubleword Caching Inhibited
Indexed instruction for TCE invalidation.

This new feature is going to be utilized by real mode support of VFIO.

Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru
---
Changes:
2013/08/07:
* tested on p7ioc and fixed a bug with realmode addresses

Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru
---
 arch/powerpc/include/asm/machdep.h| 12 +
 arch/powerpc/platforms/powernv/pci-ioda.c | 43 ++-
 arch/powerpc/platforms/powernv/pci.c  | 38 ++-
 arch/powerpc/platforms/powernv/pci.h  |  3 ++-
 4 files changed, 77 insertions(+), 19 deletions(-)

diff --git a/arch/powerpc/include/asm/machdep.h 
b/arch/powerpc/include/asm/machdep.h
index 92386fc..0c19eef 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -75,6 +75,18 @@ struct machdep_calls {
long index);
void(*tce_flush)(struct iommu_table *tbl);
 
+   /* _rm versions are for real mode use only */
+   int (*tce_build_rm)(struct iommu_table *tbl,
+long index,
+long npages,
+unsigned long uaddr,
+enum dma_data_direction direction,
+struct dma_attrs *attrs);
+   void(*tce_free_rm)(struct iommu_table *tbl,
+   long index,
+   long npages);
+   void(*tce_flush_rm)(struct iommu_table *tbl);
+
void __iomem *  (*ioremap)(phys_addr_t addr, unsigned long size,
   unsigned long flags, void *caller);
void(*iounmap)(volatile void __iomem *token);
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index d200594..8a70003 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -68,6 +68,12 @@ define_pe_printk_level(pe_err, KERN_ERR);
 define_pe_printk_level(pe_warn, KERN_WARNING);
 define_pe_printk_level(pe_info, KERN_INFO);
 
+static inline void __raw_rm_writeq(u64 val, volatile void __iomem *paddr)
+{
+   __asm__ __volatile__(stdcix %0,0,%1
+   : : r (val), r (paddr) : memory);
+}
+
 static int pnv_ioda_alloc_pe(struct pnv_phb *phb)
 {
unsigned long pe;
@@ -452,10 +458,13 @@ static void pnv_ioda_setup_bus_dma(struct pnv_ioda_pe 
*pe, struct pci_bus *bus)
}
 }
 
-static void pnv_pci_ioda1_tce_invalidate(struct iommu_table *tbl,
-u64 *startp, u64 *endp)
+static void pnv_pci_ioda1_tce_invalidate(struct pnv_ioda_pe *pe,
+struct iommu_table *tbl,
+u64 *startp, u64 *endp, bool rm)
 {
-   u64 __iomem *invalidate = (u64 __iomem *)tbl-it_index;
+   u64 __iomem *invalidate = rm?
+   (u64 __iomem *)pe-it_index_rm:
+   (u64 __iomem *)tbl-it_index;
unsigned long start, end, inc;
 
start = __pa(startp);
@@ -482,7 +491,10 @@ static void pnv_pci_ioda1_tce_invalidate(struct 
iommu_table *tbl,
 
 mb(); /* Ensure above stores are visible */
 while (start = end) {
-__raw_writeq(start, invalidate);
+   if (rm)
+   __raw_rm_writeq(start, invalidate);
+   else
+   __raw_writeq(start, invalidate);
 start += inc;
 }
 
@@ -494,10 +506,12 @@ static void pnv_pci_ioda1_tce_invalidate(struct 
iommu_table *tbl,
 
 static void pnv_pci_ioda2_tce_invalidate(struct pnv_ioda_pe *pe,
 struct iommu_table *tbl,
-u64 *startp, u64 *endp)
+u64 *startp, u64 *endp, bool rm)
 {
unsigned long start, end, inc;
-   u64 __iomem *invalidate = (u64 __iomem *)tbl-it_index;
+   u64 __iomem *invalidate = rm?
+   (u64 __iomem *)pe-it_index_rm:
+   (u64 __iomem *)tbl-it_index;
 
/* We'll invalidate DMA address in PE scope */
start = 0x2ul  60;
@@ -513,22 +527,25 @@ static void pnv_pci_ioda2_tce_invalidate(struct 
pnv_ioda_pe *pe,
mb();
 
while (start = end) {
-   __raw_writeq(start, invalidate);
+   if (rm)
+   __raw_rm_writeq(start, invalidate);
+   else
+   __raw_writeq(start, invalidate);
start += inc;
}
 }
 
 void