diff options
| author | Olof Johansson <olof@lixom.net> | 2006-04-28 23:51:59 -0400 |
|---|---|---|
| committer | Paul Mackerras <paulus@samba.org> | 2006-04-29 04:07:54 -0400 |
| commit | bc97ce951cfb697eaac9d5b6a2fbe4544fdf1a7c (patch) | |
| tree | ae880181c00f47a28e805f5328ab7e9a15620ee9 | |
| parent | c7f0e8cb5654a50986c6097b3c0cca972e406899 (diff) | |
[PATCH] powerpc: kill union tce_entry
It's been long overdue to kill the union tce_entry in the pSeries/iSeries
TCE code, especially since I asked the Summit guys to do it on the code
they copied from us.
Also, while I was at it, I cleaned up some whitespace.
Built and booted on pSeries, built on iSeries.
Signed-off-by: Olof Johansson <olof@lixom.net>
Signed-off-by: Paul Mackerras <paulus@samba.org>
| -rw-r--r-- | arch/powerpc/platforms/iseries/iommu.c | 21 | ||||
| -rw-r--r-- | arch/powerpc/platforms/pseries/iommu.c | 122 | ||||
| -rw-r--r-- | include/asm-powerpc/tce.h | 35 |
3 files changed, 71 insertions, 107 deletions
diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c index a8d96314c982..3ac22065c424 100644 --- a/arch/powerpc/platforms/iseries/iommu.c +++ b/arch/powerpc/platforms/iseries/iommu.c | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | * Rewrite, cleanup: | 4 | * Rewrite, cleanup: |
| 5 | * | 5 | * |
| 6 | * Copyright (C) 2004 Olof Johansson <olof@lixom.net>, IBM Corporation | 6 | * Copyright (C) 2004 Olof Johansson <olof@lixom.net>, IBM Corporation |
| 7 | * Copyright (C) 2006 Olof Johansson <olof@lixom.net> | ||
| 7 | * | 8 | * |
| 8 | * Dynamic DMA mapping support, iSeries-specific parts. | 9 | * Dynamic DMA mapping support, iSeries-specific parts. |
| 9 | * | 10 | * |
| @@ -42,30 +43,28 @@ static void tce_build_iSeries(struct iommu_table *tbl, long index, long npages, | |||
| 42 | unsigned long uaddr, enum dma_data_direction direction) | 43 | unsigned long uaddr, enum dma_data_direction direction) |
| 43 | { | 44 | { |
| 44 | u64 rc; | 45 | u64 rc; |
| 45 | union tce_entry tce; | 46 | u64 tce, rpn; |
| 46 | 47 | ||
| 47 | index <<= TCE_PAGE_FACTOR; | 48 | index <<= TCE_PAGE_FACTOR; |
| 48 | npages <<= TCE_PAGE_FACTOR; | 49 | npages <<= TCE_PAGE_FACTOR; |
| 49 | 50 | ||
| 50 | while (npages--) { | 51 | while (npages--) { |
| 51 | tce.te_word = 0; | 52 | rpn = virt_to_abs(uaddr) >> TCE_SHIFT; |
| 52 | tce.te_bits.tb_rpn = virt_to_abs(uaddr) >> TCE_SHIFT; | 53 | tce = (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT; |
| 53 | 54 | ||
| 54 | if (tbl->it_type == TCE_VB) { | 55 | if (tbl->it_type == TCE_VB) { |
| 55 | /* Virtual Bus */ | 56 | /* Virtual Bus */ |
| 56 | tce.te_bits.tb_valid = 1; | 57 | tce |= TCE_VALID|TCE_ALLIO; |
| 57 | tce.te_bits.tb_allio = 1; | ||
| 58 | if (direction != DMA_TO_DEVICE) | 58 | if (direction != DMA_TO_DEVICE) |
| 59 | tce.te_bits.tb_rdwr = 1; | 59 | tce |= TCE_VB_WRITE; |
| 60 | } else { | 60 | } else { |
| 61 | /* PCI Bus */ | 61 | /* PCI Bus */ |
| 62 | tce.te_bits.tb_rdwr = 1; /* Read allowed */ | 62 | tce |= TCE_PCI_READ; /* Read allowed */ |
| 63 | if (direction != DMA_TO_DEVICE) | 63 | if (direction != DMA_TO_DEVICE) |
| 64 | tce.te_bits.tb_pciwr = 1; | 64 | tce |= TCE_PCI_WRITE; |
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | rc = HvCallXm_setTce((u64)tbl->it_index, (u64)index, | 67 | rc = HvCallXm_setTce((u64)tbl->it_index, (u64)index, tce); |
| 68 | tce.te_word); | ||
| 69 | if (rc) | 68 | if (rc) |
| 70 | panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%lx\n", | 69 | panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%lx\n", |
| 71 | rc); | 70 | rc); |
| @@ -123,7 +122,7 @@ void iommu_table_getparms_iSeries(unsigned long busno, | |||
| 123 | 122 | ||
| 124 | /* itc_size is in pages worth of table, it_size is in # of entries */ | 123 | /* itc_size is in pages worth of table, it_size is in # of entries */ |
| 125 | tbl->it_size = ((parms->itc_size * TCE_PAGE_SIZE) / | 124 | tbl->it_size = ((parms->itc_size * TCE_PAGE_SIZE) / |
| 126 | sizeof(union tce_entry)) >> TCE_PAGE_FACTOR; | 125 | TCE_ENTRY_SIZE) >> TCE_PAGE_FACTOR; |
| 127 | tbl->it_busno = parms->itc_busno; | 126 | tbl->it_busno = parms->itc_busno; |
| 128 | tbl->it_offset = parms->itc_offset >> TCE_PAGE_FACTOR; | 127 | tbl->it_offset = parms->itc_offset >> TCE_PAGE_FACTOR; |
| 129 | tbl->it_index = parms->itc_index; | 128 | tbl->it_index = parms->itc_index; |
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index 2643078433f0..ed102f390689 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c | |||
| @@ -1,23 +1,24 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation | 2 | * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation |
| 3 | * | 3 | * |
| 4 | * Rewrite, cleanup: | 4 | * Rewrite, cleanup: |
| 5 | * | 5 | * |
| 6 | * Copyright (C) 2004 Olof Johansson <olof@lixom.net>, IBM Corporation | 6 | * Copyright (C) 2004 Olof Johansson <olof@lixom.net>, IBM Corporation |
| 7 | * Copyright (C) 2006 Olof Johansson <olof@lixom.net> | ||
| 7 | * | 8 | * |
| 8 | * Dynamic DMA mapping support, pSeries-specific parts, both SMP and LPAR. | 9 | * Dynamic DMA mapping support, pSeries-specific parts, both SMP and LPAR. |
| 9 | * | 10 | * |
| 10 | * | 11 | * |
| 11 | * This program is free software; you can redistribute it and/or modify | 12 | * This program is free software; you can redistribute it and/or modify |
| 12 | * it under the terms of the GNU General Public License as published by | 13 | * it under the terms of the GNU General Public License as published by |
| 13 | * the Free Software Foundation; either version 2 of the License, or | 14 | * the Free Software Foundation; either version 2 of the License, or |
| 14 | * (at your option) any later version. | 15 | * (at your option) any later version. |
| 15 | * | 16 | * |
| 16 | * This program is distributed in the hope that it will be useful, | 17 | * This program is distributed in the hope that it will be useful, |
| 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 19 | * GNU General Public License for more details. | 20 | * GNU General Public License for more details. |
| 20 | * | 21 | * |
| 21 | * You should have received a copy of the GNU General Public License | 22 | * You should have received a copy of the GNU General Public License |
| 22 | * along with this program; if not, write to the Free Software | 23 | * along with this program; if not, write to the Free Software |
| 23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 24 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| @@ -49,52 +50,46 @@ | |||
| 49 | 50 | ||
| 50 | #define DBG(fmt...) | 51 | #define DBG(fmt...) |
| 51 | 52 | ||
| 52 | static void tce_build_pSeries(struct iommu_table *tbl, long index, | 53 | static void tce_build_pSeries(struct iommu_table *tbl, long index, |
| 53 | long npages, unsigned long uaddr, | 54 | long npages, unsigned long uaddr, |
| 54 | enum dma_data_direction direction) | 55 | enum dma_data_direction direction) |
| 55 | { | 56 | { |
| 56 | union tce_entry t; | 57 | u64 proto_tce; |
| 57 | union tce_entry *tp; | 58 | u64 *tcep; |
| 59 | u64 rpn; | ||
| 58 | 60 | ||
| 59 | index <<= TCE_PAGE_FACTOR; | 61 | index <<= TCE_PAGE_FACTOR; |
| 60 | npages <<= TCE_PAGE_FACTOR; | 62 | npages <<= TCE_PAGE_FACTOR; |
| 61 | 63 | ||
| 62 | t.te_word = 0; | 64 | proto_tce = TCE_PCI_READ; // Read allowed |
| 63 | t.te_rdwr = 1; // Read allowed | ||
| 64 | 65 | ||
| 65 | if (direction != DMA_TO_DEVICE) | 66 | if (direction != DMA_TO_DEVICE) |
| 66 | t.te_pciwr = 1; | 67 | proto_tce |= TCE_PCI_WRITE; |
| 67 | 68 | ||
| 68 | tp = ((union tce_entry *)tbl->it_base) + index; | 69 | tcep = ((u64 *)tbl->it_base) + index; |
| 69 | 70 | ||
| 70 | while (npages--) { | 71 | while (npages--) { |
| 71 | /* can't move this out since we might cross LMB boundary */ | 72 | /* can't move this out since we might cross LMB boundary */ |
| 72 | t.te_rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; | 73 | rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; |
| 73 | 74 | *tcep = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT; | |
| 74 | tp->te_word = t.te_word; | ||
| 75 | 75 | ||
| 76 | uaddr += TCE_PAGE_SIZE; | 76 | uaddr += TCE_PAGE_SIZE; |
| 77 | tp++; | 77 | tcep++; |
| 78 | } | 78 | } |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | 81 | ||
| 82 | static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages) | 82 | static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages) |
| 83 | { | 83 | { |
| 84 | union tce_entry t; | 84 | u64 *tcep; |
| 85 | union tce_entry *tp; | ||
| 86 | 85 | ||
| 87 | npages <<= TCE_PAGE_FACTOR; | 86 | npages <<= TCE_PAGE_FACTOR; |
| 88 | index <<= TCE_PAGE_FACTOR; | 87 | index <<= TCE_PAGE_FACTOR; |
| 89 | 88 | ||
| 90 | t.te_word = 0; | 89 | tcep = ((u64 *)tbl->it_base) + index; |
| 91 | tp = ((union tce_entry *)tbl->it_base) + index; | 90 | |
| 92 | 91 | while (npages--) | |
| 93 | while (npages--) { | 92 | *(tcep++) = 0; |
| 94 | tp->te_word = t.te_word; | ||
| 95 | |||
| 96 | tp++; | ||
| 97 | } | ||
| 98 | } | 93 | } |
| 99 | 94 | ||
| 100 | 95 | ||
| @@ -103,43 +98,44 @@ static void tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum, | |||
| 103 | enum dma_data_direction direction) | 98 | enum dma_data_direction direction) |
| 104 | { | 99 | { |
| 105 | u64 rc; | 100 | u64 rc; |
| 106 | union tce_entry tce; | 101 | u64 proto_tce, tce; |
| 102 | u64 rpn; | ||
| 107 | 103 | ||
| 108 | tcenum <<= TCE_PAGE_FACTOR; | 104 | tcenum <<= TCE_PAGE_FACTOR; |
| 109 | npages <<= TCE_PAGE_FACTOR; | 105 | npages <<= TCE_PAGE_FACTOR; |
| 110 | 106 | ||
| 111 | tce.te_word = 0; | 107 | rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; |
| 112 | tce.te_rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; | 108 | proto_tce = TCE_PCI_READ; |
| 113 | tce.te_rdwr = 1; | ||
| 114 | if (direction != DMA_TO_DEVICE) | 109 | if (direction != DMA_TO_DEVICE) |
| 115 | tce.te_pciwr = 1; | 110 | proto_tce |= TCE_PCI_WRITE; |
| 116 | 111 | ||
| 117 | while (npages--) { | 112 | while (npages--) { |
| 118 | rc = plpar_tce_put((u64)tbl->it_index, | 113 | tce = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT; |
| 119 | (u64)tcenum << 12, | 114 | rc = plpar_tce_put((u64)tbl->it_index, (u64)tcenum << 12, tce); |
| 120 | tce.te_word ); | 115 | |
| 121 | |||
| 122 | if (rc && printk_ratelimit()) { | 116 | if (rc && printk_ratelimit()) { |
| 123 | printk("tce_build_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc); | 117 | printk("tce_build_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc); |
| 124 | printk("\tindex = 0x%lx\n", (u64)tbl->it_index); | 118 | printk("\tindex = 0x%lx\n", (u64)tbl->it_index); |
| 125 | printk("\ttcenum = 0x%lx\n", (u64)tcenum); | 119 | printk("\ttcenum = 0x%lx\n", (u64)tcenum); |
| 126 | printk("\ttce val = 0x%lx\n", tce.te_word ); | 120 | printk("\ttce val = 0x%lx\n", tce ); |
| 127 | show_stack(current, (unsigned long *)__get_SP()); | 121 | show_stack(current, (unsigned long *)__get_SP()); |
| 128 | } | 122 | } |
| 129 | 123 | ||
| 130 | tcenum++; | 124 | tcenum++; |
| 131 | tce.te_rpn++; | 125 | rpn++; |
| 132 | } | 126 | } |
| 133 | } | 127 | } |
| 134 | 128 | ||
| 135 | static DEFINE_PER_CPU(void *, tce_page) = NULL; | 129 | static DEFINE_PER_CPU(u64 *, tce_page) = NULL; |
| 136 | 130 | ||
| 137 | static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, | 131 | static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, |
| 138 | long npages, unsigned long uaddr, | 132 | long npages, unsigned long uaddr, |
| 139 | enum dma_data_direction direction) | 133 | enum dma_data_direction direction) |
| 140 | { | 134 | { |
| 141 | u64 rc; | 135 | u64 rc; |
| 142 | union tce_entry tce, *tcep; | 136 | u64 proto_tce; |
| 137 | u64 *tcep; | ||
| 138 | u64 rpn; | ||
| 143 | long l, limit; | 139 | long l, limit; |
| 144 | 140 | ||
| 145 | if (TCE_PAGE_FACTOR == 0 && npages == 1) | 141 | if (TCE_PAGE_FACTOR == 0 && npages == 1) |
| @@ -152,7 +148,7 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, | |||
| 152 | * from iommu_alloc{,_sg}() | 148 | * from iommu_alloc{,_sg}() |
| 153 | */ | 149 | */ |
| 154 | if (!tcep) { | 150 | if (!tcep) { |
| 155 | tcep = (void *)__get_free_page(GFP_ATOMIC); | 151 | tcep = (u64 *)__get_free_page(GFP_ATOMIC); |
| 156 | /* If allocation fails, fall back to the loop implementation */ | 152 | /* If allocation fails, fall back to the loop implementation */ |
| 157 | if (!tcep) | 153 | if (!tcep) |
| 158 | return tce_build_pSeriesLP(tbl, tcenum, npages, | 154 | return tce_build_pSeriesLP(tbl, tcenum, npages, |
| @@ -163,11 +159,10 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, | |||
| 163 | tcenum <<= TCE_PAGE_FACTOR; | 159 | tcenum <<= TCE_PAGE_FACTOR; |
| 164 | npages <<= TCE_PAGE_FACTOR; | 160 | npages <<= TCE_PAGE_FACTOR; |
| 165 | 161 | ||
| 166 | tce.te_word = 0; | 162 | rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; |
| 167 | tce.te_rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; | 163 | proto_tce = TCE_PCI_READ; |
| 168 | tce.te_rdwr = 1; | ||
| 169 | if (direction != DMA_TO_DEVICE) | 164 | if (direction != DMA_TO_DEVICE) |
| 170 | tce.te_pciwr = 1; | 165 | proto_tce |= TCE_PCI_WRITE; |
| 171 | 166 | ||
| 172 | /* We can map max one pageful of TCEs at a time */ | 167 | /* We can map max one pageful of TCEs at a time */ |
| 173 | do { | 168 | do { |
| @@ -175,11 +170,11 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, | |||
| 175 | * Set up the page with TCE data, looping through and setting | 170 | * Set up the page with TCE data, looping through and setting |
| 176 | * the values. | 171 | * the values. |
| 177 | */ | 172 | */ |
| 178 | limit = min_t(long, npages, 4096/sizeof(union tce_entry)); | 173 | limit = min_t(long, npages, 4096/TCE_ENTRY_SIZE); |
| 179 | 174 | ||
| 180 | for (l = 0; l < limit; l++) { | 175 | for (l = 0; l < limit; l++) { |
| 181 | tcep[l] = tce; | 176 | tcep[l] = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT; |
| 182 | tce.te_rpn++; | 177 | rpn++; |
| 183 | } | 178 | } |
| 184 | 179 | ||
| 185 | rc = plpar_tce_put_indirect((u64)tbl->it_index, | 180 | rc = plpar_tce_put_indirect((u64)tbl->it_index, |
| @@ -195,7 +190,7 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, | |||
| 195 | printk("tce_buildmulti_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc); | 190 | printk("tce_buildmulti_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc); |
| 196 | printk("\tindex = 0x%lx\n", (u64)tbl->it_index); | 191 | printk("\tindex = 0x%lx\n", (u64)tbl->it_index); |
| 197 | printk("\tnpages = 0x%lx\n", (u64)npages); | 192 | printk("\tnpages = 0x%lx\n", (u64)npages); |
| 198 | printk("\ttce[0] val = 0x%lx\n", tcep[0].te_word); | 193 | printk("\ttce[0] val = 0x%lx\n", tcep[0]); |
| 199 | show_stack(current, (unsigned long *)__get_SP()); | 194 | show_stack(current, (unsigned long *)__get_SP()); |
| 200 | } | 195 | } |
| 201 | } | 196 | } |
| @@ -203,23 +198,17 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, | |||
| 203 | static void tce_free_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages) | 198 | static void tce_free_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages) |
| 204 | { | 199 | { |
| 205 | u64 rc; | 200 | u64 rc; |
| 206 | union tce_entry tce; | ||
| 207 | 201 | ||
| 208 | tcenum <<= TCE_PAGE_FACTOR; | 202 | tcenum <<= TCE_PAGE_FACTOR; |
| 209 | npages <<= TCE_PAGE_FACTOR; | 203 | npages <<= TCE_PAGE_FACTOR; |
| 210 | 204 | ||
| 211 | tce.te_word = 0; | ||
| 212 | |||
| 213 | while (npages--) { | 205 | while (npages--) { |
| 214 | rc = plpar_tce_put((u64)tbl->it_index, | 206 | rc = plpar_tce_put((u64)tbl->it_index, (u64)tcenum << 12, 0); |
| 215 | (u64)tcenum << 12, | ||
| 216 | tce.te_word); | ||
| 217 | 207 | ||
| 218 | if (rc && printk_ratelimit()) { | 208 | if (rc && printk_ratelimit()) { |
| 219 | printk("tce_free_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc); | 209 | printk("tce_free_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc); |
| 220 | printk("\tindex = 0x%lx\n", (u64)tbl->it_index); | 210 | printk("\tindex = 0x%lx\n", (u64)tbl->it_index); |
| 221 | printk("\ttcenum = 0x%lx\n", (u64)tcenum); | 211 | printk("\ttcenum = 0x%lx\n", (u64)tcenum); |
| 222 | printk("\ttce val = 0x%lx\n", tce.te_word ); | ||
| 223 | show_stack(current, (unsigned long *)__get_SP()); | 212 | show_stack(current, (unsigned long *)__get_SP()); |
| 224 | } | 213 | } |
| 225 | 214 | ||
| @@ -231,31 +220,24 @@ static void tce_free_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages | |||
| 231 | static void tce_freemulti_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages) | 220 | static void tce_freemulti_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages) |
| 232 | { | 221 | { |
| 233 | u64 rc; | 222 | u64 rc; |
| 234 | union tce_entry tce; | ||
| 235 | 223 | ||
| 236 | tcenum <<= TCE_PAGE_FACTOR; | 224 | tcenum <<= TCE_PAGE_FACTOR; |
| 237 | npages <<= TCE_PAGE_FACTOR; | 225 | npages <<= TCE_PAGE_FACTOR; |
| 238 | 226 | ||
| 239 | tce.te_word = 0; | 227 | rc = plpar_tce_stuff((u64)tbl->it_index, (u64)tcenum << 12, 0, npages); |
| 240 | |||
| 241 | rc = plpar_tce_stuff((u64)tbl->it_index, | ||
| 242 | (u64)tcenum << 12, | ||
| 243 | tce.te_word, | ||
| 244 | npages); | ||
| 245 | 228 | ||
| 246 | if (rc && printk_ratelimit()) { | 229 | if (rc && printk_ratelimit()) { |
| 247 | printk("tce_freemulti_pSeriesLP: plpar_tce_stuff failed\n"); | 230 | printk("tce_freemulti_pSeriesLP: plpar_tce_stuff failed\n"); |
| 248 | printk("\trc = %ld\n", rc); | 231 | printk("\trc = %ld\n", rc); |
| 249 | printk("\tindex = 0x%lx\n", (u64)tbl->it_index); | 232 | printk("\tindex = 0x%lx\n", (u64)tbl->it_index); |
| 250 | printk("\tnpages = 0x%lx\n", (u64)npages); | 233 | printk("\tnpages = 0x%lx\n", (u64)npages); |
| 251 | printk("\ttce val = 0x%lx\n", tce.te_word ); | ||
| 252 | show_stack(current, (unsigned long *)__get_SP()); | 234 | show_stack(current, (unsigned long *)__get_SP()); |
| 253 | } | 235 | } |
| 254 | } | 236 | } |
| 255 | 237 | ||
| 256 | static void iommu_table_setparms(struct pci_controller *phb, | 238 | static void iommu_table_setparms(struct pci_controller *phb, |
| 257 | struct device_node *dn, | 239 | struct device_node *dn, |
| 258 | struct iommu_table *tbl) | 240 | struct iommu_table *tbl) |
| 259 | { | 241 | { |
| 260 | struct device_node *node; | 242 | struct device_node *node; |
| 261 | unsigned long *basep; | 243 | unsigned long *basep; |
| @@ -275,16 +257,16 @@ static void iommu_table_setparms(struct pci_controller *phb, | |||
| 275 | memset((void *)tbl->it_base, 0, *sizep); | 257 | memset((void *)tbl->it_base, 0, *sizep); |
| 276 | 258 | ||
| 277 | tbl->it_busno = phb->bus->number; | 259 | tbl->it_busno = phb->bus->number; |
| 278 | 260 | ||
| 279 | /* Units of tce entries */ | 261 | /* Units of tce entries */ |
| 280 | tbl->it_offset = phb->dma_window_base_cur >> PAGE_SHIFT; | 262 | tbl->it_offset = phb->dma_window_base_cur >> PAGE_SHIFT; |
| 281 | 263 | ||
| 282 | /* Test if we are going over 2GB of DMA space */ | 264 | /* Test if we are going over 2GB of DMA space */ |
| 283 | if (phb->dma_window_base_cur + phb->dma_window_size > 0x80000000ul) { | 265 | if (phb->dma_window_base_cur + phb->dma_window_size > 0x80000000ul) { |
| 284 | udbg_printf("PCI_DMA: Unexpected number of IOAs under this PHB.\n"); | 266 | udbg_printf("PCI_DMA: Unexpected number of IOAs under this PHB.\n"); |
| 285 | panic("PCI_DMA: Unexpected number of IOAs under this PHB.\n"); | 267 | panic("PCI_DMA: Unexpected number of IOAs under this PHB.\n"); |
| 286 | } | 268 | } |
| 287 | 269 | ||
| 288 | phb->dma_window_base_cur += phb->dma_window_size; | 270 | phb->dma_window_base_cur += phb->dma_window_size; |
| 289 | 271 | ||
| 290 | /* Set the tce table size - measured in entries */ | 272 | /* Set the tce table size - measured in entries */ |
| @@ -442,7 +424,7 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus) | |||
| 442 | 424 | ||
| 443 | tbl = (struct iommu_table *)kmalloc(sizeof(struct iommu_table), | 425 | tbl = (struct iommu_table *)kmalloc(sizeof(struct iommu_table), |
| 444 | GFP_KERNEL); | 426 | GFP_KERNEL); |
| 445 | 427 | ||
| 446 | iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window); | 428 | iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window); |
| 447 | 429 | ||
| 448 | ppci->iommu_table = iommu_init_table(tbl); | 430 | ppci->iommu_table = iommu_init_table(tbl); |
diff --git a/include/asm-powerpc/tce.h b/include/asm-powerpc/tce.h index 6fa200ad7a7f..c9483adbf599 100644 --- a/include/asm-powerpc/tce.h +++ b/include/asm-powerpc/tce.h | |||
| @@ -35,32 +35,15 @@ | |||
| 35 | #define TCE_PAGE_SIZE (1 << TCE_SHIFT) | 35 | #define TCE_PAGE_SIZE (1 << TCE_SHIFT) |
| 36 | #define TCE_PAGE_FACTOR (PAGE_SHIFT - TCE_SHIFT) | 36 | #define TCE_PAGE_FACTOR (PAGE_SHIFT - TCE_SHIFT) |
| 37 | 37 | ||
| 38 | 38 | #define TCE_ENTRY_SIZE 8 /* each TCE is 64 bits */ | |
| 39 | /* tce_entry | 39 | |
| 40 | * Used by pSeries (SMP) and iSeries/pSeries LPAR, but there it's | 40 | #define TCE_RPN_MASK 0xfffffffffful /* 40-bit RPN (4K pages) */ |
| 41 | * abstracted so layout is irrelevant. | 41 | #define TCE_RPN_SHIFT 12 |
| 42 | */ | 42 | #define TCE_VALID 0x800 /* TCE valid */ |
| 43 | union tce_entry { | 43 | #define TCE_ALLIO 0x400 /* TCE valid for all lpars */ |
| 44 | unsigned long te_word; | 44 | #define TCE_PCI_WRITE 0x2 /* write from PCI allowed */ |
| 45 | struct { | 45 | #define TCE_PCI_READ 0x1 /* read from PCI allowed */ |
| 46 | unsigned int tb_cacheBits :6; /* Cache hash bits - not used */ | 46 | #define TCE_VB_WRITE 0x1 /* write from VB allowed */ |
| 47 | unsigned int tb_rsvd :6; | ||
| 48 | unsigned long tb_rpn :40; /* Real page number */ | ||
| 49 | unsigned int tb_valid :1; /* Tce is valid (vb only) */ | ||
| 50 | unsigned int tb_allio :1; /* Tce is valid for all lps (vb only) */ | ||
| 51 | unsigned int tb_lpindex :8; /* LpIndex for user of TCE (vb only) */ | ||
| 52 | unsigned int tb_pciwr :1; /* Write allowed (pci only) */ | ||
| 53 | unsigned int tb_rdwr :1; /* Read allowed (pci), Write allowed (vb) */ | ||
| 54 | } te_bits; | ||
| 55 | #define te_cacheBits te_bits.tb_cacheBits | ||
| 56 | #define te_rpn te_bits.tb_rpn | ||
| 57 | #define te_valid te_bits.tb_valid | ||
| 58 | #define te_allio te_bits.tb_allio | ||
| 59 | #define te_lpindex te_bits.tb_lpindex | ||
| 60 | #define te_pciwr te_bits.tb_pciwr | ||
| 61 | #define te_rdwr te_bits.tb_rdwr | ||
| 62 | }; | ||
| 63 | |||
| 64 | 47 | ||
| 65 | #endif /* __KERNEL__ */ | 48 | #endif /* __KERNEL__ */ |
| 66 | #endif /* _ASM_POWERPC_TCE_H */ | 49 | #endif /* _ASM_POWERPC_TCE_H */ |
