aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2006-04-28 23:51:59 -0400
committerPaul Mackerras <paulus@samba.org>2006-04-29 04:07:54 -0400
commitbc97ce951cfb697eaac9d5b6a2fbe4544fdf1a7c (patch)
treeae880181c00f47a28e805f5328ab7e9a15620ee9
parentc7f0e8cb5654a50986c6097b3c0cca972e406899 (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.c21
-rw-r--r--arch/powerpc/platforms/pseries/iommu.c122
-rw-r--r--include/asm-powerpc/tce.h35
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
52static void tce_build_pSeries(struct iommu_table *tbl, long index, 53static 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
82static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages) 82static 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
135static DEFINE_PER_CPU(void *, tce_page) = NULL; 129static DEFINE_PER_CPU(u64 *, tce_page) = NULL;
136 130
137static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, 131static 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,
203static void tce_free_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages) 198static 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
231static void tce_freemulti_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages) 220static 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
256static void iommu_table_setparms(struct pci_controller *phb, 238static 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 */
43union 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 */