diff options
-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 */ |