aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/mm/iommu.c
diff options
context:
space:
mode:
authorDavid Woodhouse <David.Woodhouse@intel.com>2008-10-13 12:13:56 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2008-10-13 12:13:56 -0400
commite758936e02700ff88a0b08b722a3847b95283ef2 (patch)
tree50c919bef1b459a778b85159d5929de95b6c4a01 /arch/sparc/mm/iommu.c
parent239cfbde1f5843c4a24199f117d5f67f637d72d5 (diff)
parent4480f15b3306f43bbb0310d461142b4e897ca45b (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts: include/asm-x86/statfs.h
Diffstat (limited to 'arch/sparc/mm/iommu.c')
-rw-r--r--arch/sparc/mm/iommu.c113
1 files changed, 55 insertions, 58 deletions
diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c
index 4b934270f05e..e7a499e3aa3c 100644
--- a/arch/sparc/mm/iommu.c
+++ b/arch/sparc/mm/iommu.c
@@ -13,10 +13,11 @@
13#include <linux/slab.h> 13#include <linux/slab.h>
14#include <linux/highmem.h> /* pte_offset_map => kmap_atomic */ 14#include <linux/highmem.h> /* pte_offset_map => kmap_atomic */
15#include <linux/scatterlist.h> 15#include <linux/scatterlist.h>
16#include <linux/of.h>
17#include <linux/of_device.h>
16 18
17#include <asm/pgalloc.h> 19#include <asm/pgalloc.h>
18#include <asm/pgtable.h> 20#include <asm/pgtable.h>
19#include <asm/sbus.h>
20#include <asm/io.h> 21#include <asm/io.h>
21#include <asm/mxcc.h> 22#include <asm/mxcc.h>
22#include <asm/mbus.h> 23#include <asm/mbus.h>
@@ -55,30 +56,21 @@ static pgprot_t dvma_prot; /* Consistent mapping pte flags */
55#define IOPERM (IOPTE_CACHE | IOPTE_WRITE | IOPTE_VALID) 56#define IOPERM (IOPTE_CACHE | IOPTE_WRITE | IOPTE_VALID)
56#define MKIOPTE(pfn, perm) (((((pfn)<<8) & IOPTE_PAGE) | (perm)) & ~IOPTE_WAZ) 57#define MKIOPTE(pfn, perm) (((((pfn)<<8) & IOPTE_PAGE) | (perm)) & ~IOPTE_WAZ)
57 58
58void __init 59static void __init sbus_iommu_init(struct of_device *op)
59iommu_init(int iommund, struct sbus_bus *sbus)
60{ 60{
61 unsigned int impl, vers;
62 unsigned long tmp;
63 struct iommu_struct *iommu; 61 struct iommu_struct *iommu;
64 struct linux_prom_registers iommu_promregs[PROMREG_MAX]; 62 unsigned int impl, vers;
65 struct resource r;
66 unsigned long *bitmap; 63 unsigned long *bitmap;
64 unsigned long tmp;
67 65
68 iommu = kmalloc(sizeof(struct iommu_struct), GFP_ATOMIC); 66 iommu = kmalloc(sizeof(struct iommu_struct), GFP_ATOMIC);
69 if (!iommu) { 67 if (!iommu) {
70 prom_printf("Unable to allocate iommu structure\n"); 68 prom_printf("Unable to allocate iommu structure\n");
71 prom_halt(); 69 prom_halt();
72 } 70 }
73 iommu->regs = NULL; 71
74 if (prom_getproperty(iommund, "reg", (void *) iommu_promregs, 72 iommu->regs = of_ioremap(&op->resource[0], 0, PAGE_SIZE * 3,
75 sizeof(iommu_promregs)) != -1) { 73 "iommu_regs");
76 memset(&r, 0, sizeof(r));
77 r.flags = iommu_promregs[0].which_io;
78 r.start = iommu_promregs[0].phys_addr;
79 iommu->regs = (struct iommu_regs *)
80 sbus_ioremap(&r, 0, PAGE_SIZE * 3, "iommu_regs");
81 }
82 if (!iommu->regs) { 74 if (!iommu->regs) {
83 prom_printf("Cannot map IOMMU registers\n"); 75 prom_printf("Cannot map IOMMU registers\n");
84 prom_halt(); 76 prom_halt();
@@ -128,13 +120,29 @@ iommu_init(int iommund, struct sbus_bus *sbus)
128 else 120 else
129 iommu->usemap.num_colors = 1; 121 iommu->usemap.num_colors = 1;
130 122
131 printk("IOMMU: impl %d vers %d table 0x%p[%d B] map [%d b]\n", 123 printk(KERN_INFO "IOMMU: impl %d vers %d table 0x%p[%d B] map [%d b]\n",
132 impl, vers, iommu->page_table, 124 impl, vers, iommu->page_table,
133 (int)(IOMMU_NPTES*sizeof(iopte_t)), (int)IOMMU_NPTES); 125 (int)(IOMMU_NPTES*sizeof(iopte_t)), (int)IOMMU_NPTES);
126
127 op->dev.archdata.iommu = iommu;
128}
129
130static int __init iommu_init(void)
131{
132 struct device_node *dp;
133
134 for_each_node_by_name(dp, "iommu") {
135 struct of_device *op = of_find_device_by_node(dp);
136
137 sbus_iommu_init(op);
138 of_propagate_archdata(op);
139 }
134 140
135 sbus->ofdev.dev.archdata.iommu = iommu; 141 return 0;
136} 142}
137 143
144subsys_initcall(iommu_init);
145
138/* This begs to be btfixup-ed by srmmu. */ 146/* This begs to be btfixup-ed by srmmu. */
139/* Flush the iotlb entries to ram. */ 147/* Flush the iotlb entries to ram. */
140/* This could be better if we didn't have to flush whole pages. */ 148/* This could be better if we didn't have to flush whole pages. */
@@ -164,9 +172,9 @@ static void iommu_flush_iotlb(iopte_t *iopte, unsigned int niopte)
164 } 172 }
165} 173}
166 174
167static u32 iommu_get_one(struct page *page, int npages, struct sbus_bus *sbus) 175static u32 iommu_get_one(struct device *dev, struct page *page, int npages)
168{ 176{
169 struct iommu_struct *iommu = sbus->ofdev.dev.archdata.iommu; 177 struct iommu_struct *iommu = dev->archdata.iommu;
170 int ioptex; 178 int ioptex;
171 iopte_t *iopte, *iopte0; 179 iopte_t *iopte, *iopte0;
172 unsigned int busa, busa0; 180 unsigned int busa, busa0;
@@ -194,8 +202,7 @@ static u32 iommu_get_one(struct page *page, int npages, struct sbus_bus *sbus)
194 return busa0; 202 return busa0;
195} 203}
196 204
197static u32 iommu_get_scsi_one(char *vaddr, unsigned int len, 205static u32 iommu_get_scsi_one(struct device *dev, char *vaddr, unsigned int len)
198 struct sbus_bus *sbus)
199{ 206{
200 unsigned long off; 207 unsigned long off;
201 int npages; 208 int npages;
@@ -205,22 +212,22 @@ static u32 iommu_get_scsi_one(char *vaddr, unsigned int len,
205 off = (unsigned long)vaddr & ~PAGE_MASK; 212 off = (unsigned long)vaddr & ~PAGE_MASK;
206 npages = (off + len + PAGE_SIZE-1) >> PAGE_SHIFT; 213 npages = (off + len + PAGE_SIZE-1) >> PAGE_SHIFT;
207 page = virt_to_page((unsigned long)vaddr & PAGE_MASK); 214 page = virt_to_page((unsigned long)vaddr & PAGE_MASK);
208 busa = iommu_get_one(page, npages, sbus); 215 busa = iommu_get_one(dev, page, npages);
209 return busa + off; 216 return busa + off;
210} 217}
211 218
212static __u32 iommu_get_scsi_one_noflush(char *vaddr, unsigned long len, struct sbus_bus *sbus) 219static __u32 iommu_get_scsi_one_noflush(struct device *dev, char *vaddr, unsigned long len)
213{ 220{
214 return iommu_get_scsi_one(vaddr, len, sbus); 221 return iommu_get_scsi_one(dev, vaddr, len);
215} 222}
216 223
217static __u32 iommu_get_scsi_one_gflush(char *vaddr, unsigned long len, struct sbus_bus *sbus) 224static __u32 iommu_get_scsi_one_gflush(struct device *dev, char *vaddr, unsigned long len)
218{ 225{
219 flush_page_for_dma(0); 226 flush_page_for_dma(0);
220 return iommu_get_scsi_one(vaddr, len, sbus); 227 return iommu_get_scsi_one(dev, vaddr, len);
221} 228}
222 229
223static __u32 iommu_get_scsi_one_pflush(char *vaddr, unsigned long len, struct sbus_bus *sbus) 230static __u32 iommu_get_scsi_one_pflush(struct device *dev, char *vaddr, unsigned long len)
224{ 231{
225 unsigned long page = ((unsigned long) vaddr) & PAGE_MASK; 232 unsigned long page = ((unsigned long) vaddr) & PAGE_MASK;
226 233
@@ -228,23 +235,23 @@ static __u32 iommu_get_scsi_one_pflush(char *vaddr, unsigned long len, struct sb
228 flush_page_for_dma(page); 235 flush_page_for_dma(page);
229 page += PAGE_SIZE; 236 page += PAGE_SIZE;
230 } 237 }
231 return iommu_get_scsi_one(vaddr, len, sbus); 238 return iommu_get_scsi_one(dev, vaddr, len);
232} 239}
233 240
234static void iommu_get_scsi_sgl_noflush(struct scatterlist *sg, int sz, struct sbus_bus *sbus) 241static void iommu_get_scsi_sgl_noflush(struct device *dev, struct scatterlist *sg, int sz)
235{ 242{
236 int n; 243 int n;
237 244
238 while (sz != 0) { 245 while (sz != 0) {
239 --sz; 246 --sz;
240 n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT; 247 n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT;
241 sg->dvma_address = iommu_get_one(sg_page(sg), n, sbus) + sg->offset; 248 sg->dvma_address = iommu_get_one(dev, sg_page(sg), n) + sg->offset;
242 sg->dvma_length = (__u32) sg->length; 249 sg->dvma_length = (__u32) sg->length;
243 sg = sg_next(sg); 250 sg = sg_next(sg);
244 } 251 }
245} 252}
246 253
247static void iommu_get_scsi_sgl_gflush(struct scatterlist *sg, int sz, struct sbus_bus *sbus) 254static void iommu_get_scsi_sgl_gflush(struct device *dev, struct scatterlist *sg, int sz)
248{ 255{
249 int n; 256 int n;
250 257
@@ -252,13 +259,13 @@ static void iommu_get_scsi_sgl_gflush(struct scatterlist *sg, int sz, struct sbu
252 while (sz != 0) { 259 while (sz != 0) {
253 --sz; 260 --sz;
254 n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT; 261 n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT;
255 sg->dvma_address = iommu_get_one(sg_page(sg), n, sbus) + sg->offset; 262 sg->dvma_address = iommu_get_one(dev, sg_page(sg), n) + sg->offset;
256 sg->dvma_length = (__u32) sg->length; 263 sg->dvma_length = (__u32) sg->length;
257 sg = sg_next(sg); 264 sg = sg_next(sg);
258 } 265 }
259} 266}
260 267
261static void iommu_get_scsi_sgl_pflush(struct scatterlist *sg, int sz, struct sbus_bus *sbus) 268static void iommu_get_scsi_sgl_pflush(struct device *dev, struct scatterlist *sg, int sz)
262{ 269{
263 unsigned long page, oldpage = 0; 270 unsigned long page, oldpage = 0;
264 int n, i; 271 int n, i;
@@ -283,15 +290,15 @@ static void iommu_get_scsi_sgl_pflush(struct scatterlist *sg, int sz, struct sbu
283 } 290 }
284 } 291 }
285 292
286 sg->dvma_address = iommu_get_one(sg_page(sg), n, sbus) + sg->offset; 293 sg->dvma_address = iommu_get_one(dev, sg_page(sg), n) + sg->offset;
287 sg->dvma_length = (__u32) sg->length; 294 sg->dvma_length = (__u32) sg->length;
288 sg = sg_next(sg); 295 sg = sg_next(sg);
289 } 296 }
290} 297}
291 298
292static void iommu_release_one(u32 busa, int npages, struct sbus_bus *sbus) 299static void iommu_release_one(struct device *dev, u32 busa, int npages)
293{ 300{
294 struct iommu_struct *iommu = sbus->ofdev.dev.archdata.iommu; 301 struct iommu_struct *iommu = dev->archdata.iommu;
295 int ioptex; 302 int ioptex;
296 int i; 303 int i;
297 304
@@ -305,17 +312,17 @@ static void iommu_release_one(u32 busa, int npages, struct sbus_bus *sbus)
305 bit_map_clear(&iommu->usemap, ioptex, npages); 312 bit_map_clear(&iommu->usemap, ioptex, npages);
306} 313}
307 314
308static void iommu_release_scsi_one(__u32 vaddr, unsigned long len, struct sbus_bus *sbus) 315static void iommu_release_scsi_one(struct device *dev, __u32 vaddr, unsigned long len)
309{ 316{
310 unsigned long off; 317 unsigned long off;
311 int npages; 318 int npages;
312 319
313 off = vaddr & ~PAGE_MASK; 320 off = vaddr & ~PAGE_MASK;
314 npages = (off + len + PAGE_SIZE-1) >> PAGE_SHIFT; 321 npages = (off + len + PAGE_SIZE-1) >> PAGE_SHIFT;
315 iommu_release_one(vaddr & PAGE_MASK, npages, sbus); 322 iommu_release_one(dev, vaddr & PAGE_MASK, npages);
316} 323}
317 324
318static void iommu_release_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus *sbus) 325static void iommu_release_scsi_sgl(struct device *dev, struct scatterlist *sg, int sz)
319{ 326{
320 int n; 327 int n;
321 328
@@ -323,18 +330,18 @@ static void iommu_release_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_b
323 --sz; 330 --sz;
324 331
325 n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT; 332 n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT;
326 iommu_release_one(sg->dvma_address & PAGE_MASK, n, sbus); 333 iommu_release_one(dev, sg->dvma_address & PAGE_MASK, n);
327 sg->dvma_address = 0x21212121; 334 sg->dvma_address = 0x21212121;
328 sg = sg_next(sg); 335 sg = sg_next(sg);
329 } 336 }
330} 337}
331 338
332#ifdef CONFIG_SBUS 339#ifdef CONFIG_SBUS
333static int iommu_map_dma_area(dma_addr_t *pba, unsigned long va, 340static int iommu_map_dma_area(struct device *dev, dma_addr_t *pba, unsigned long va,
334 unsigned long addr, int len) 341 unsigned long addr, int len)
335{ 342{
343 struct iommu_struct *iommu = dev->archdata.iommu;
336 unsigned long page, end; 344 unsigned long page, end;
337 struct iommu_struct *iommu = sbus_root->ofdev.dev.archdata.iommu;
338 iopte_t *iopte = iommu->page_table; 345 iopte_t *iopte = iommu->page_table;
339 iopte_t *first; 346 iopte_t *first;
340 int ioptex; 347 int ioptex;
@@ -397,9 +404,9 @@ static int iommu_map_dma_area(dma_addr_t *pba, unsigned long va,
397 return 0; 404 return 0;
398} 405}
399 406
400static void iommu_unmap_dma_area(unsigned long busa, int len) 407static void iommu_unmap_dma_area(struct device *dev, unsigned long busa, int len)
401{ 408{
402 struct iommu_struct *iommu = sbus_root->ofdev.dev.archdata.iommu; 409 struct iommu_struct *iommu = dev->archdata.iommu;
403 iopte_t *iopte = iommu->page_table; 410 iopte_t *iopte = iommu->page_table;
404 unsigned long end; 411 unsigned long end;
405 int ioptex = (busa - iommu->start) >> PAGE_SHIFT; 412 int ioptex = (busa - iommu->start) >> PAGE_SHIFT;
@@ -417,15 +424,6 @@ static void iommu_unmap_dma_area(unsigned long busa, int len)
417 iommu_invalidate(iommu->regs); 424 iommu_invalidate(iommu->regs);
418 bit_map_clear(&iommu->usemap, ioptex, len >> PAGE_SHIFT); 425 bit_map_clear(&iommu->usemap, ioptex, len >> PAGE_SHIFT);
419} 426}
420
421static struct page *iommu_translate_dvma(unsigned long busa)
422{
423 struct iommu_struct *iommu = sbus_root->ofdev.dev.archdata.iommu;
424 iopte_t *iopte = iommu->page_table;
425
426 iopte += ((busa - iommu->start) >> PAGE_SHIFT);
427 return pfn_to_page((iopte_val(*iopte) & IOPTE_PAGE) >> (PAGE_SHIFT-4));
428}
429#endif 427#endif
430 428
431static char *iommu_lockarea(char *vaddr, unsigned long len) 429static char *iommu_lockarea(char *vaddr, unsigned long len)
@@ -461,7 +459,6 @@ void __init ld_mmu_iommu(void)
461#ifdef CONFIG_SBUS 459#ifdef CONFIG_SBUS
462 BTFIXUPSET_CALL(mmu_map_dma_area, iommu_map_dma_area, BTFIXUPCALL_NORM); 460 BTFIXUPSET_CALL(mmu_map_dma_area, iommu_map_dma_area, BTFIXUPCALL_NORM);
463 BTFIXUPSET_CALL(mmu_unmap_dma_area, iommu_unmap_dma_area, BTFIXUPCALL_NORM); 461 BTFIXUPSET_CALL(mmu_unmap_dma_area, iommu_unmap_dma_area, BTFIXUPCALL_NORM);
464 BTFIXUPSET_CALL(mmu_translate_dvma, iommu_translate_dvma, BTFIXUPCALL_NORM);
465#endif 462#endif
466 463
467 if (viking_mxcc_present || srmmu_modtype == HyperSparc) { 464 if (viking_mxcc_present || srmmu_modtype == HyperSparc) {