diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-10-13 04:52:30 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-10-13 04:52:30 -0400 |
commit | c493756e2a8a78bcaae30668317890dcfe86e7c3 (patch) | |
tree | 8fb40782e79472ed882ff2098d4dd295557278ee /arch/sparc/mm | |
parent | 0d15504f16f68725e4635aa85411015d1c573b0a (diff) | |
parent | 4480f15b3306f43bbb0310d461142b4e897ca45b (diff) |
Merge branch 'linus' into oprofile
Conflicts:
arch/x86/kernel/apic_32.c
include/linux/pci_ids.h
Diffstat (limited to 'arch/sparc/mm')
-rw-r--r-- | arch/sparc/mm/Makefile | 9 | ||||
-rw-r--r-- | arch/sparc/mm/btfixup.c | 6 | ||||
-rw-r--r-- | arch/sparc/mm/fault.c | 2 | ||||
-rw-r--r-- | arch/sparc/mm/init.c | 14 | ||||
-rw-r--r-- | arch/sparc/mm/io-unit.c | 136 | ||||
-rw-r--r-- | arch/sparc/mm/iommu.c | 113 | ||||
-rw-r--r-- | arch/sparc/mm/nosrmmu.c | 59 | ||||
-rw-r--r-- | arch/sparc/mm/srmmu.c | 1 | ||||
-rw-r--r-- | arch/sparc/mm/sun4c.c | 204 |
9 files changed, 161 insertions, 383 deletions
diff --git a/arch/sparc/mm/Makefile b/arch/sparc/mm/Makefile index 109c8b22cb38..ea88955d97ff 100644 --- a/arch/sparc/mm/Makefile +++ b/arch/sparc/mm/Makefile | |||
@@ -3,13 +3,8 @@ | |||
3 | 3 | ||
4 | EXTRA_AFLAGS := -ansi | 4 | EXTRA_AFLAGS := -ansi |
5 | 5 | ||
6 | obj-y := fault.o init.o loadmmu.o generic.o extable.o btfixup.o | 6 | obj-y := fault.o init.o loadmmu.o generic.o extable.o btfixup.o \ |
7 | 7 | srmmu.o iommu.o io-unit.o hypersparc.o viking.o tsunami.o swift.o | |
8 | ifeq ($(CONFIG_SUN4),y) | ||
9 | obj-y += nosrmmu.o | ||
10 | else | ||
11 | obj-y += srmmu.o iommu.o io-unit.o hypersparc.o viking.o tsunami.o swift.o | ||
12 | endif | ||
13 | 8 | ||
14 | ifdef CONFIG_HIGHMEM | 9 | ifdef CONFIG_HIGHMEM |
15 | obj-y += highmem.o | 10 | obj-y += highmem.o |
diff --git a/arch/sparc/mm/btfixup.c b/arch/sparc/mm/btfixup.c index a312d127d47a..5175ac2f4820 100644 --- a/arch/sparc/mm/btfixup.c +++ b/arch/sparc/mm/btfixup.c | |||
@@ -20,11 +20,7 @@ | |||
20 | 20 | ||
21 | extern char *srmmu_name; | 21 | extern char *srmmu_name; |
22 | static char version[] __initdata = "Boot time fixup v1.6. 4/Mar/98 Jakub Jelinek (jj@ultra.linux.cz). Patching kernel for "; | 22 | static char version[] __initdata = "Boot time fixup v1.6. 4/Mar/98 Jakub Jelinek (jj@ultra.linux.cz). Patching kernel for "; |
23 | #ifdef CONFIG_SUN4 | ||
24 | static char str_sun4c[] __initdata = "sun4\n"; | ||
25 | #else | ||
26 | static char str_sun4c[] __initdata = "sun4c\n"; | 23 | static char str_sun4c[] __initdata = "sun4c\n"; |
27 | #endif | ||
28 | static char str_srmmu[] __initdata = "srmmu[%s]/"; | 24 | static char str_srmmu[] __initdata = "srmmu[%s]/"; |
29 | static char str_iommu[] __initdata = "iommu\n"; | 25 | static char str_iommu[] __initdata = "iommu\n"; |
30 | static char str_iounit[] __initdata = "io-unit\n"; | 26 | static char str_iounit[] __initdata = "io-unit\n"; |
@@ -86,7 +82,7 @@ void __init btfixup(void) | |||
86 | if (!visited) { | 82 | if (!visited) { |
87 | visited++; | 83 | visited++; |
88 | printk(version); | 84 | printk(version); |
89 | if (ARCH_SUN4C_SUN4) | 85 | if (ARCH_SUN4C) |
90 | printk(str_sun4c); | 86 | printk(str_sun4c); |
91 | else { | 87 | else { |
92 | printk(str_srmmu, srmmu_name); | 88 | printk(str_srmmu, srmmu_name); |
diff --git a/arch/sparc/mm/fault.c b/arch/sparc/mm/fault.c index 3604c2e86709..a507e1174662 100644 --- a/arch/sparc/mm/fault.c +++ b/arch/sparc/mm/fault.c | |||
@@ -191,7 +191,7 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write, | |||
191 | * only copy the information from the master page table, | 191 | * only copy the information from the master page table, |
192 | * nothing more. | 192 | * nothing more. |
193 | */ | 193 | */ |
194 | if (!ARCH_SUN4C_SUN4 && address >= TASK_SIZE) | 194 | if (!ARCH_SUN4C && address >= TASK_SIZE) |
195 | goto vmalloc_fault; | 195 | goto vmalloc_fault; |
196 | 196 | ||
197 | info.si_code = SEGV_MAPERR; | 197 | info.si_code = SEGV_MAPERR; |
diff --git a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c index e103f1bb3777..677c1e187a23 100644 --- a/arch/sparc/mm/init.c +++ b/arch/sparc/mm/init.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/highmem.h> | 23 | #include <linux/highmem.h> |
24 | #include <linux/bootmem.h> | 24 | #include <linux/bootmem.h> |
25 | #include <linux/pagemap.h> | 25 | #include <linux/pagemap.h> |
26 | #include <linux/poison.h> | ||
26 | 27 | ||
27 | #include <asm/system.h> | 28 | #include <asm/system.h> |
28 | #include <asm/vac-ops.h> | 29 | #include <asm/vac-ops.h> |
@@ -480,6 +481,7 @@ void free_initmem (void) | |||
480 | for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) { | 481 | for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) { |
481 | struct page *p; | 482 | struct page *p; |
482 | 483 | ||
484 | memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE); | ||
483 | p = virt_to_page(addr); | 485 | p = virt_to_page(addr); |
484 | 486 | ||
485 | ClearPageReserved(p); | 487 | ClearPageReserved(p); |
@@ -488,20 +490,26 @@ void free_initmem (void) | |||
488 | totalram_pages++; | 490 | totalram_pages++; |
489 | num_physpages++; | 491 | num_physpages++; |
490 | } | 492 | } |
491 | printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10); | 493 | printk(KERN_INFO "Freeing unused kernel memory: %dk freed\n", |
494 | (&__init_end - &__init_begin) >> 10); | ||
492 | } | 495 | } |
493 | 496 | ||
494 | #ifdef CONFIG_BLK_DEV_INITRD | 497 | #ifdef CONFIG_BLK_DEV_INITRD |
495 | void free_initrd_mem(unsigned long start, unsigned long end) | 498 | void free_initrd_mem(unsigned long start, unsigned long end) |
496 | { | 499 | { |
497 | if (start < end) | 500 | if (start < end) |
498 | printk (KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) >> 10); | 501 | printk(KERN_INFO "Freeing initrd memory: %ldk freed\n", |
502 | (end - start) >> 10); | ||
499 | for (; start < end; start += PAGE_SIZE) { | 503 | for (; start < end; start += PAGE_SIZE) { |
500 | struct page *p = virt_to_page(start); | 504 | struct page *p; |
505 | |||
506 | memset((void *)start, POISON_FREE_INITMEM, PAGE_SIZE); | ||
507 | p = virt_to_page(start); | ||
501 | 508 | ||
502 | ClearPageReserved(p); | 509 | ClearPageReserved(p); |
503 | init_page_count(p); | 510 | init_page_count(p); |
504 | __free_page(p); | 511 | __free_page(p); |
512 | totalram_pages++; | ||
505 | num_physpages++; | 513 | num_physpages++; |
506 | } | 514 | } |
507 | } | 515 | } |
diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c index f167835db3df..daadf5f88050 100644 --- a/arch/sparc/mm/io-unit.c +++ b/arch/sparc/mm/io-unit.c | |||
@@ -12,10 +12,11 @@ | |||
12 | #include <linux/highmem.h> /* pte_offset_map => kmap_atomic */ | 12 | #include <linux/highmem.h> /* pte_offset_map => kmap_atomic */ |
13 | #include <linux/bitops.h> | 13 | #include <linux/bitops.h> |
14 | #include <linux/scatterlist.h> | 14 | #include <linux/scatterlist.h> |
15 | #include <linux/of.h> | ||
16 | #include <linux/of_device.h> | ||
15 | 17 | ||
16 | #include <asm/pgalloc.h> | 18 | #include <asm/pgalloc.h> |
17 | #include <asm/pgtable.h> | 19 | #include <asm/pgtable.h> |
18 | #include <asm/sbus.h> | ||
19 | #include <asm/io.h> | 20 | #include <asm/io.h> |
20 | #include <asm/io-unit.h> | 21 | #include <asm/io-unit.h> |
21 | #include <asm/mxcc.h> | 22 | #include <asm/mxcc.h> |
@@ -34,13 +35,10 @@ | |||
34 | #define IOPERM (IOUPTE_CACHE | IOUPTE_WRITE | IOUPTE_VALID) | 35 | #define IOPERM (IOUPTE_CACHE | IOUPTE_WRITE | IOUPTE_VALID) |
35 | #define MKIOPTE(phys) __iopte((((phys)>>4) & IOUPTE_PAGE) | IOPERM) | 36 | #define MKIOPTE(phys) __iopte((((phys)>>4) & IOUPTE_PAGE) | IOPERM) |
36 | 37 | ||
37 | void __init | 38 | static void __init iounit_iommu_init(struct of_device *op) |
38 | iounit_init(int sbi_node, int io_node, struct sbus_bus *sbus) | ||
39 | { | 39 | { |
40 | iopte_t *xpt, *xptend; | ||
41 | struct iounit_struct *iounit; | 40 | struct iounit_struct *iounit; |
42 | struct linux_prom_registers iommu_promregs[PROMREG_MAX]; | 41 | iopte_t *xpt, *xptend; |
43 | struct resource r; | ||
44 | 42 | ||
45 | iounit = kzalloc(sizeof(struct iounit_struct), GFP_ATOMIC); | 43 | iounit = kzalloc(sizeof(struct iounit_struct), GFP_ATOMIC); |
46 | if (!iounit) { | 44 | if (!iounit) { |
@@ -55,18 +53,13 @@ iounit_init(int sbi_node, int io_node, struct sbus_bus *sbus) | |||
55 | iounit->rotor[1] = IOUNIT_BMAP2_START; | 53 | iounit->rotor[1] = IOUNIT_BMAP2_START; |
56 | iounit->rotor[2] = IOUNIT_BMAPM_START; | 54 | iounit->rotor[2] = IOUNIT_BMAPM_START; |
57 | 55 | ||
58 | xpt = NULL; | 56 | xpt = of_ioremap(&op->resource[2], 0, PAGE_SIZE * 16, "XPT"); |
59 | if(prom_getproperty(sbi_node, "reg", (void *) iommu_promregs, | 57 | if (!xpt) { |
60 | sizeof(iommu_promregs)) != -1) { | 58 | prom_printf("SUN4D: Cannot map External Page Table."); |
61 | prom_apply_generic_ranges(io_node, 0, iommu_promregs, 3); | 59 | prom_halt(); |
62 | memset(&r, 0, sizeof(r)); | ||
63 | r.flags = iommu_promregs[2].which_io; | ||
64 | r.start = iommu_promregs[2].phys_addr; | ||
65 | xpt = (iopte_t *) sbus_ioremap(&r, 0, PAGE_SIZE * 16, "XPT"); | ||
66 | } | 60 | } |
67 | if(!xpt) panic("Cannot map External Page Table."); | ||
68 | 61 | ||
69 | sbus->ofdev.dev.archdata.iommu = iounit; | 62 | op->dev.archdata.iommu = iounit; |
70 | iounit->page_table = xpt; | 63 | iounit->page_table = xpt; |
71 | spin_lock_init(&iounit->lock); | 64 | spin_lock_init(&iounit->lock); |
72 | 65 | ||
@@ -75,6 +68,25 @@ iounit_init(int sbi_node, int io_node, struct sbus_bus *sbus) | |||
75 | iopte_val(*xpt++) = 0; | 68 | iopte_val(*xpt++) = 0; |
76 | } | 69 | } |
77 | 70 | ||
71 | static int __init iounit_init(void) | ||
72 | { | ||
73 | extern void sun4d_init_sbi_irq(void); | ||
74 | struct device_node *dp; | ||
75 | |||
76 | for_each_node_by_name(dp, "sbi") { | ||
77 | struct of_device *op = of_find_device_by_node(dp); | ||
78 | |||
79 | iounit_iommu_init(op); | ||
80 | of_propagate_archdata(op); | ||
81 | } | ||
82 | |||
83 | sun4d_init_sbi_irq(); | ||
84 | |||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | subsys_initcall(iounit_init); | ||
89 | |||
78 | /* One has to hold iounit->lock to call this */ | 90 | /* One has to hold iounit->lock to call this */ |
79 | static unsigned long iounit_get_area(struct iounit_struct *iounit, unsigned long vaddr, int size) | 91 | static unsigned long iounit_get_area(struct iounit_struct *iounit, unsigned long vaddr, int size) |
80 | { | 92 | { |
@@ -124,10 +136,10 @@ nexti: scan = find_next_zero_bit(iounit->bmap, limit, scan); | |||
124 | return vaddr; | 136 | return vaddr; |
125 | } | 137 | } |
126 | 138 | ||
127 | static __u32 iounit_get_scsi_one(char *vaddr, unsigned long len, struct sbus_bus *sbus) | 139 | static __u32 iounit_get_scsi_one(struct device *dev, char *vaddr, unsigned long len) |
128 | { | 140 | { |
141 | struct iounit_struct *iounit = dev->archdata.iommu; | ||
129 | unsigned long ret, flags; | 142 | unsigned long ret, flags; |
130 | struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu; | ||
131 | 143 | ||
132 | spin_lock_irqsave(&iounit->lock, flags); | 144 | spin_lock_irqsave(&iounit->lock, flags); |
133 | ret = iounit_get_area(iounit, (unsigned long)vaddr, len); | 145 | ret = iounit_get_area(iounit, (unsigned long)vaddr, len); |
@@ -135,10 +147,10 @@ static __u32 iounit_get_scsi_one(char *vaddr, unsigned long len, struct sbus_bus | |||
135 | return ret; | 147 | return ret; |
136 | } | 148 | } |
137 | 149 | ||
138 | static void iounit_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus *sbus) | 150 | static void iounit_get_scsi_sgl(struct device *dev, struct scatterlist *sg, int sz) |
139 | { | 151 | { |
152 | struct iounit_struct *iounit = dev->archdata.iommu; | ||
140 | unsigned long flags; | 153 | unsigned long flags; |
141 | struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu; | ||
142 | 154 | ||
143 | /* FIXME: Cache some resolved pages - often several sg entries are to the same page */ | 155 | /* FIXME: Cache some resolved pages - often several sg entries are to the same page */ |
144 | spin_lock_irqsave(&iounit->lock, flags); | 156 | spin_lock_irqsave(&iounit->lock, flags); |
@@ -151,10 +163,10 @@ static void iounit_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus | |||
151 | spin_unlock_irqrestore(&iounit->lock, flags); | 163 | spin_unlock_irqrestore(&iounit->lock, flags); |
152 | } | 164 | } |
153 | 165 | ||
154 | static void iounit_release_scsi_one(__u32 vaddr, unsigned long len, struct sbus_bus *sbus) | 166 | static void iounit_release_scsi_one(struct device *dev, __u32 vaddr, unsigned long len) |
155 | { | 167 | { |
168 | struct iounit_struct *iounit = dev->archdata.iommu; | ||
156 | unsigned long flags; | 169 | unsigned long flags; |
157 | struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu; | ||
158 | 170 | ||
159 | spin_lock_irqsave(&iounit->lock, flags); | 171 | spin_lock_irqsave(&iounit->lock, flags); |
160 | len = ((vaddr & ~PAGE_MASK) + len + (PAGE_SIZE-1)) >> PAGE_SHIFT; | 172 | len = ((vaddr & ~PAGE_MASK) + len + (PAGE_SIZE-1)) >> PAGE_SHIFT; |
@@ -165,11 +177,11 @@ static void iounit_release_scsi_one(__u32 vaddr, unsigned long len, struct sbus_ | |||
165 | spin_unlock_irqrestore(&iounit->lock, flags); | 177 | spin_unlock_irqrestore(&iounit->lock, flags); |
166 | } | 178 | } |
167 | 179 | ||
168 | static void iounit_release_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus *sbus) | 180 | static void iounit_release_scsi_sgl(struct device *dev, struct scatterlist *sg, int sz) |
169 | { | 181 | { |
182 | struct iounit_struct *iounit = dev->archdata.iommu; | ||
170 | unsigned long flags; | 183 | unsigned long flags; |
171 | unsigned long vaddr, len; | 184 | unsigned long vaddr, len; |
172 | struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu; | ||
173 | 185 | ||
174 | spin_lock_irqsave(&iounit->lock, flags); | 186 | spin_lock_irqsave(&iounit->lock, flags); |
175 | while (sz != 0) { | 187 | while (sz != 0) { |
@@ -185,12 +197,12 @@ static void iounit_release_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_ | |||
185 | } | 197 | } |
186 | 198 | ||
187 | #ifdef CONFIG_SBUS | 199 | #ifdef CONFIG_SBUS |
188 | static int iounit_map_dma_area(dma_addr_t *pba, unsigned long va, __u32 addr, int len) | 200 | static int iounit_map_dma_area(struct device *dev, dma_addr_t *pba, unsigned long va, __u32 addr, int len) |
189 | { | 201 | { |
202 | struct iounit_struct *iounit = dev->archdata.iommu; | ||
190 | unsigned long page, end; | 203 | unsigned long page, end; |
191 | pgprot_t dvma_prot; | 204 | pgprot_t dvma_prot; |
192 | iopte_t *iopte; | 205 | iopte_t *iopte; |
193 | struct sbus_bus *sbus; | ||
194 | 206 | ||
195 | *pba = addr; | 207 | *pba = addr; |
196 | 208 | ||
@@ -212,12 +224,8 @@ static int iounit_map_dma_area(dma_addr_t *pba, unsigned long va, __u32 addr, in | |||
212 | 224 | ||
213 | i = ((addr - IOUNIT_DMA_BASE) >> PAGE_SHIFT); | 225 | i = ((addr - IOUNIT_DMA_BASE) >> PAGE_SHIFT); |
214 | 226 | ||
215 | for_each_sbus(sbus) { | 227 | iopte = (iopte_t *)(iounit->page_table + i); |
216 | struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu; | 228 | *iopte = MKIOPTE(__pa(page)); |
217 | |||
218 | iopte = (iopte_t *)(iounit->page_table + i); | ||
219 | *iopte = MKIOPTE(__pa(page)); | ||
220 | } | ||
221 | } | 229 | } |
222 | addr += PAGE_SIZE; | 230 | addr += PAGE_SIZE; |
223 | va += PAGE_SIZE; | 231 | va += PAGE_SIZE; |
@@ -228,23 +236,10 @@ static int iounit_map_dma_area(dma_addr_t *pba, unsigned long va, __u32 addr, in | |||
228 | return 0; | 236 | return 0; |
229 | } | 237 | } |
230 | 238 | ||
231 | static void iounit_unmap_dma_area(unsigned long addr, int len) | 239 | static void iounit_unmap_dma_area(struct device *dev, unsigned long addr, int len) |
232 | { | 240 | { |
233 | /* XXX Somebody please fill this in */ | 241 | /* XXX Somebody please fill this in */ |
234 | } | 242 | } |
235 | |||
236 | /* XXX We do not pass sbus device here, bad. */ | ||
237 | static struct page *iounit_translate_dvma(unsigned long addr) | ||
238 | { | ||
239 | struct sbus_bus *sbus = sbus_root; /* They are all the same */ | ||
240 | struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu; | ||
241 | int i; | ||
242 | iopte_t *iopte; | ||
243 | |||
244 | i = ((addr - IOUNIT_DMA_BASE) >> PAGE_SHIFT); | ||
245 | iopte = (iopte_t *)(iounit->page_table + i); | ||
246 | return pfn_to_page(iopte_val(*iopte) >> (PAGE_SHIFT-4)); /* XXX sun4d guru, help */ | ||
247 | } | ||
248 | #endif | 243 | #endif |
249 | 244 | ||
250 | static char *iounit_lockarea(char *vaddr, unsigned long len) | 245 | static char *iounit_lockarea(char *vaddr, unsigned long len) |
@@ -271,54 +266,5 @@ void __init ld_mmu_iounit(void) | |||
271 | #ifdef CONFIG_SBUS | 266 | #ifdef CONFIG_SBUS |
272 | BTFIXUPSET_CALL(mmu_map_dma_area, iounit_map_dma_area, BTFIXUPCALL_NORM); | 267 | BTFIXUPSET_CALL(mmu_map_dma_area, iounit_map_dma_area, BTFIXUPCALL_NORM); |
273 | BTFIXUPSET_CALL(mmu_unmap_dma_area, iounit_unmap_dma_area, BTFIXUPCALL_NORM); | 268 | BTFIXUPSET_CALL(mmu_unmap_dma_area, iounit_unmap_dma_area, BTFIXUPCALL_NORM); |
274 | BTFIXUPSET_CALL(mmu_translate_dvma, iounit_translate_dvma, BTFIXUPCALL_NORM); | ||
275 | #endif | 269 | #endif |
276 | } | 270 | } |
277 | |||
278 | __u32 iounit_map_dma_init(struct sbus_bus *sbus, int size) | ||
279 | { | ||
280 | int i, j, k, npages; | ||
281 | unsigned long rotor, scan, limit; | ||
282 | unsigned long flags; | ||
283 | __u32 ret; | ||
284 | struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu; | ||
285 | |||
286 | npages = (size + (PAGE_SIZE-1)) >> PAGE_SHIFT; | ||
287 | i = 0x0213; | ||
288 | spin_lock_irqsave(&iounit->lock, flags); | ||
289 | next: j = (i & 15); | ||
290 | rotor = iounit->rotor[j - 1]; | ||
291 | limit = iounit->limit[j]; | ||
292 | scan = rotor; | ||
293 | nexti: scan = find_next_zero_bit(iounit->bmap, limit, scan); | ||
294 | if (scan + npages > limit) { | ||
295 | if (limit != rotor) { | ||
296 | limit = rotor; | ||
297 | scan = iounit->limit[j - 1]; | ||
298 | goto nexti; | ||
299 | } | ||
300 | i >>= 4; | ||
301 | if (!(i & 15)) | ||
302 | panic("iounit_map_dma_init: Couldn't find free iopte slots for %d bytes\n", size); | ||
303 | goto next; | ||
304 | } | ||
305 | for (k = 1, scan++; k < npages; k++) | ||
306 | if (test_bit(scan++, iounit->bmap)) | ||
307 | goto nexti; | ||
308 | iounit->rotor[j - 1] = (scan < limit) ? scan : iounit->limit[j - 1]; | ||
309 | scan -= npages; | ||
310 | ret = IOUNIT_DMA_BASE + (scan << PAGE_SHIFT); | ||
311 | for (k = 0; k < npages; k++, scan++) | ||
312 | set_bit(scan, iounit->bmap); | ||
313 | spin_unlock_irqrestore(&iounit->lock, flags); | ||
314 | return ret; | ||
315 | } | ||
316 | |||
317 | __u32 iounit_map_dma_page(__u32 vaddr, void *addr, struct sbus_bus *sbus) | ||
318 | { | ||
319 | int scan = (vaddr - IOUNIT_DMA_BASE) >> PAGE_SHIFT; | ||
320 | struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu; | ||
321 | |||
322 | iounit->page_table[scan] = MKIOPTE(__pa(((unsigned long)addr) & PAGE_MASK)); | ||
323 | return vaddr + (((unsigned long)addr) & ~PAGE_MASK); | ||
324 | } | ||
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 | ||
58 | void __init | 59 | static void __init sbus_iommu_init(struct of_device *op) |
59 | iommu_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 | |||
130 | static 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 | ||
144 | subsys_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 | ||
167 | static u32 iommu_get_one(struct page *page, int npages, struct sbus_bus *sbus) | 175 | static 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 | ||
197 | static u32 iommu_get_scsi_one(char *vaddr, unsigned int len, | 205 | static 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 | ||
212 | static __u32 iommu_get_scsi_one_noflush(char *vaddr, unsigned long len, struct sbus_bus *sbus) | 219 | static __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 | ||
217 | static __u32 iommu_get_scsi_one_gflush(char *vaddr, unsigned long len, struct sbus_bus *sbus) | 224 | static __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 | ||
223 | static __u32 iommu_get_scsi_one_pflush(char *vaddr, unsigned long len, struct sbus_bus *sbus) | 230 | static __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 | ||
234 | static void iommu_get_scsi_sgl_noflush(struct scatterlist *sg, int sz, struct sbus_bus *sbus) | 241 | static 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 | ||
247 | static void iommu_get_scsi_sgl_gflush(struct scatterlist *sg, int sz, struct sbus_bus *sbus) | 254 | static 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 | ||
261 | static void iommu_get_scsi_sgl_pflush(struct scatterlist *sg, int sz, struct sbus_bus *sbus) | 268 | static 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 | ||
292 | static void iommu_release_one(u32 busa, int npages, struct sbus_bus *sbus) | 299 | static 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 | ||
308 | static void iommu_release_scsi_one(__u32 vaddr, unsigned long len, struct sbus_bus *sbus) | 315 | static 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 | ||
318 | static void iommu_release_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus *sbus) | 325 | static 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 |
333 | static int iommu_map_dma_area(dma_addr_t *pba, unsigned long va, | 340 | static 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 | ||
400 | static void iommu_unmap_dma_area(unsigned long busa, int len) | 407 | static 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 | |||
421 | static 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 | ||
431 | static char *iommu_lockarea(char *vaddr, unsigned long len) | 429 | static 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) { |
diff --git a/arch/sparc/mm/nosrmmu.c b/arch/sparc/mm/nosrmmu.c deleted file mode 100644 index 3701f70fc30a..000000000000 --- a/arch/sparc/mm/nosrmmu.c +++ /dev/null | |||
@@ -1,59 +0,0 @@ | |||
1 | /* | ||
2 | * nosrmmu.c: This file is a bunch of dummies for sun4 compiles, | ||
3 | * so that it does not need srmmu and avoid ifdefs. | ||
4 | * | ||
5 | * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) | ||
6 | */ | ||
7 | |||
8 | #include <linux/kernel.h> | ||
9 | #include <linux/mm.h> | ||
10 | #include <linux/init.h> | ||
11 | #include <asm/mbus.h> | ||
12 | #include <asm/sbus.h> | ||
13 | |||
14 | static char shouldnothappen[] __initdata = "SUN4 kernel can only run on SUN4\n"; | ||
15 | |||
16 | enum mbus_module srmmu_modtype; | ||
17 | void *srmmu_nocache_pool; | ||
18 | |||
19 | int vac_cache_size = 0; | ||
20 | |||
21 | static void __init should_not_happen(void) | ||
22 | { | ||
23 | prom_printf(shouldnothappen); | ||
24 | prom_halt(); | ||
25 | } | ||
26 | |||
27 | void __init srmmu_frob_mem_map(unsigned long start_mem) | ||
28 | { | ||
29 | should_not_happen(); | ||
30 | } | ||
31 | |||
32 | unsigned long __init srmmu_paging_init(unsigned long start_mem, unsigned long end_mem) | ||
33 | { | ||
34 | should_not_happen(); | ||
35 | return 0; | ||
36 | } | ||
37 | |||
38 | void __init ld_mmu_srmmu(void) | ||
39 | { | ||
40 | should_not_happen(); | ||
41 | } | ||
42 | |||
43 | void srmmu_mapioaddr(unsigned long physaddr, unsigned long virt_addr, int bus_type, int rdonly) | ||
44 | { | ||
45 | } | ||
46 | |||
47 | void srmmu_unmapioaddr(unsigned long virt_addr) | ||
48 | { | ||
49 | } | ||
50 | |||
51 | __u32 iounit_map_dma_init(struct sbus_bus *sbus, int size) | ||
52 | { | ||
53 | return 0; | ||
54 | } | ||
55 | |||
56 | __u32 iounit_map_dma_page(__u32 vaddr, void *addr, struct sbus_bus *sbus) | ||
57 | { | ||
58 | return 0; | ||
59 | } | ||
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c index ee30462598fc..6a5d7cabc044 100644 --- a/arch/sparc/mm/srmmu.c +++ b/arch/sparc/mm/srmmu.c | |||
@@ -31,7 +31,6 @@ | |||
31 | #include <asm/mbus.h> | 31 | #include <asm/mbus.h> |
32 | #include <asm/cache.h> | 32 | #include <asm/cache.h> |
33 | #include <asm/oplib.h> | 33 | #include <asm/oplib.h> |
34 | #include <asm/sbus.h> | ||
35 | #include <asm/asi.h> | 34 | #include <asm/asi.h> |
36 | #include <asm/msi.h> | 35 | #include <asm/msi.h> |
37 | #include <asm/mmu_context.h> | 36 | #include <asm/mmu_context.h> |
diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c index d1782f6368be..fe65aeeb3947 100644 --- a/arch/sparc/mm/sun4c.c +++ b/arch/sparc/mm/sun4c.c | |||
@@ -31,7 +31,6 @@ | |||
31 | #include <asm/oplib.h> | 31 | #include <asm/oplib.h> |
32 | #include <asm/openprom.h> | 32 | #include <asm/openprom.h> |
33 | #include <asm/mmu_context.h> | 33 | #include <asm/mmu_context.h> |
34 | #include <asm/sun4paddr.h> | ||
35 | #include <asm/highmem.h> | 34 | #include <asm/highmem.h> |
36 | #include <asm/btfixup.h> | 35 | #include <asm/btfixup.h> |
37 | #include <asm/cacheflush.h> | 36 | #include <asm/cacheflush.h> |
@@ -52,15 +51,11 @@ extern int num_segmaps, num_contexts; | |||
52 | 51 | ||
53 | extern unsigned long page_kernel; | 52 | extern unsigned long page_kernel; |
54 | 53 | ||
55 | #ifdef CONFIG_SUN4 | ||
56 | #define SUN4C_VAC_SIZE sun4c_vacinfo.num_bytes | ||
57 | #else | ||
58 | /* That's it, we prom_halt() on sun4c if the cache size is something other than 65536. | 54 | /* That's it, we prom_halt() on sun4c if the cache size is something other than 65536. |
59 | * So let's save some cycles and just use that everywhere except for that bootup | 55 | * So let's save some cycles and just use that everywhere except for that bootup |
60 | * sanity check. | 56 | * sanity check. |
61 | */ | 57 | */ |
62 | #define SUN4C_VAC_SIZE 65536 | 58 | #define SUN4C_VAC_SIZE 65536 |
63 | #endif | ||
64 | 59 | ||
65 | #define SUN4C_KERNEL_BUCKETS 32 | 60 | #define SUN4C_KERNEL_BUCKETS 32 |
66 | 61 | ||
@@ -285,75 +280,32 @@ void __init sun4c_probe_vac(void) | |||
285 | { | 280 | { |
286 | sun4c_disable_vac(); | 281 | sun4c_disable_vac(); |
287 | 282 | ||
288 | if (ARCH_SUN4) { | 283 | if ((idprom->id_machtype == (SM_SUN4C | SM_4C_SS1)) || |
289 | switch (idprom->id_machtype) { | 284 | (idprom->id_machtype == (SM_SUN4C | SM_4C_SS1PLUS))) { |
290 | 285 | /* PROM on SS1 lacks this info, to be super safe we | |
291 | case (SM_SUN4|SM_4_110): | 286 | * hard code it here since this arch is cast in stone. |
292 | sun4c_vacinfo.type = VAC_NONE; | 287 | */ |
293 | sun4c_vacinfo.num_bytes = 0; | 288 | sun4c_vacinfo.num_bytes = 65536; |
294 | sun4c_vacinfo.linesize = 0; | 289 | sun4c_vacinfo.linesize = 16; |
295 | sun4c_vacinfo.do_hwflushes = 0; | ||
296 | prom_printf("No VAC. Get some bucks and buy a real computer."); | ||
297 | prom_halt(); | ||
298 | break; | ||
299 | |||
300 | case (SM_SUN4|SM_4_260): | ||
301 | sun4c_vacinfo.type = VAC_WRITE_BACK; | ||
302 | sun4c_vacinfo.num_bytes = 128 * 1024; | ||
303 | sun4c_vacinfo.linesize = 16; | ||
304 | sun4c_vacinfo.do_hwflushes = 0; | ||
305 | break; | ||
306 | |||
307 | case (SM_SUN4|SM_4_330): | ||
308 | sun4c_vacinfo.type = VAC_WRITE_THROUGH; | ||
309 | sun4c_vacinfo.num_bytes = 128 * 1024; | ||
310 | sun4c_vacinfo.linesize = 16; | ||
311 | sun4c_vacinfo.do_hwflushes = 0; | ||
312 | break; | ||
313 | |||
314 | case (SM_SUN4|SM_4_470): | ||
315 | sun4c_vacinfo.type = VAC_WRITE_BACK; | ||
316 | sun4c_vacinfo.num_bytes = 128 * 1024; | ||
317 | sun4c_vacinfo.linesize = 32; | ||
318 | sun4c_vacinfo.do_hwflushes = 0; | ||
319 | break; | ||
320 | |||
321 | default: | ||
322 | prom_printf("Cannot initialize VAC - weird sun4 model idprom->id_machtype = %d", idprom->id_machtype); | ||
323 | prom_halt(); | ||
324 | }; | ||
325 | } else { | 290 | } else { |
326 | sun4c_vacinfo.type = VAC_WRITE_THROUGH; | 291 | sun4c_vacinfo.num_bytes = |
292 | prom_getintdefault(prom_root_node, "vac-size", 65536); | ||
293 | sun4c_vacinfo.linesize = | ||
294 | prom_getintdefault(prom_root_node, "vac-linesize", 16); | ||
295 | } | ||
296 | sun4c_vacinfo.do_hwflushes = | ||
297 | prom_getintdefault(prom_root_node, "vac-hwflush", 0); | ||
327 | 298 | ||
328 | if ((idprom->id_machtype == (SM_SUN4C | SM_4C_SS1)) || | 299 | if (sun4c_vacinfo.do_hwflushes == 0) |
329 | (idprom->id_machtype == (SM_SUN4C | SM_4C_SS1PLUS))) { | ||
330 | /* PROM on SS1 lacks this info, to be super safe we | ||
331 | * hard code it here since this arch is cast in stone. | ||
332 | */ | ||
333 | sun4c_vacinfo.num_bytes = 65536; | ||
334 | sun4c_vacinfo.linesize = 16; | ||
335 | } else { | ||
336 | sun4c_vacinfo.num_bytes = | ||
337 | prom_getintdefault(prom_root_node, "vac-size", 65536); | ||
338 | sun4c_vacinfo.linesize = | ||
339 | prom_getintdefault(prom_root_node, "vac-linesize", 16); | ||
340 | } | ||
341 | sun4c_vacinfo.do_hwflushes = | 300 | sun4c_vacinfo.do_hwflushes = |
342 | prom_getintdefault(prom_root_node, "vac-hwflush", 0); | 301 | prom_getintdefault(prom_root_node, "vac_hwflush", 0); |
343 | |||
344 | if (sun4c_vacinfo.do_hwflushes == 0) | ||
345 | sun4c_vacinfo.do_hwflushes = | ||
346 | prom_getintdefault(prom_root_node, "vac_hwflush", 0); | ||
347 | 302 | ||
348 | if (sun4c_vacinfo.num_bytes != 65536) { | 303 | if (sun4c_vacinfo.num_bytes != 65536) { |
349 | prom_printf("WEIRD Sun4C VAC cache size, " | 304 | prom_printf("WEIRD Sun4C VAC cache size, " |
350 | "tell sparclinux@vger.kernel.org"); | 305 | "tell sparclinux@vger.kernel.org"); |
351 | prom_halt(); | 306 | prom_halt(); |
352 | } | ||
353 | } | 307 | } |
354 | 308 | ||
355 | sun4c_vacinfo.num_lines = | ||
356 | (sun4c_vacinfo.num_bytes / sun4c_vacinfo.linesize); | ||
357 | switch (sun4c_vacinfo.linesize) { | 309 | switch (sun4c_vacinfo.linesize) { |
358 | case 16: | 310 | case 16: |
359 | sun4c_vacinfo.log2lsize = 4; | 311 | sun4c_vacinfo.log2lsize = 4; |
@@ -447,49 +399,18 @@ static void __init patch_kernel_fault_handler(void) | |||
447 | 399 | ||
448 | static void __init sun4c_probe_mmu(void) | 400 | static void __init sun4c_probe_mmu(void) |
449 | { | 401 | { |
450 | if (ARCH_SUN4) { | 402 | if ((idprom->id_machtype == (SM_SUN4C | SM_4C_SS1)) || |
451 | switch (idprom->id_machtype) { | 403 | (idprom->id_machtype == (SM_SUN4C | SM_4C_SS1PLUS))) { |
452 | case (SM_SUN4|SM_4_110): | 404 | /* Hardcode these just to be safe, PROM on SS1 does |
453 | prom_printf("No support for 4100 yet\n"); | 405 | * not have this info available in the root node. |
454 | prom_halt(); | 406 | */ |
455 | num_segmaps = 256; | 407 | num_segmaps = 128; |
456 | num_contexts = 8; | 408 | num_contexts = 8; |
457 | break; | ||
458 | |||
459 | case (SM_SUN4|SM_4_260): | ||
460 | /* should be 512 segmaps. when it get fixed */ | ||
461 | num_segmaps = 256; | ||
462 | num_contexts = 16; | ||
463 | break; | ||
464 | |||
465 | case (SM_SUN4|SM_4_330): | ||
466 | num_segmaps = 256; | ||
467 | num_contexts = 16; | ||
468 | break; | ||
469 | |||
470 | case (SM_SUN4|SM_4_470): | ||
471 | /* should be 1024 segmaps. when it get fixed */ | ||
472 | num_segmaps = 256; | ||
473 | num_contexts = 64; | ||
474 | break; | ||
475 | default: | ||
476 | prom_printf("Invalid SUN4 model\n"); | ||
477 | prom_halt(); | ||
478 | }; | ||
479 | } else { | 409 | } else { |
480 | if ((idprom->id_machtype == (SM_SUN4C | SM_4C_SS1)) || | 410 | num_segmaps = |
481 | (idprom->id_machtype == (SM_SUN4C | SM_4C_SS1PLUS))) { | 411 | prom_getintdefault(prom_root_node, "mmu-npmg", 128); |
482 | /* Hardcode these just to be safe, PROM on SS1 does | 412 | num_contexts = |
483 | * not have this info available in the root node. | 413 | prom_getintdefault(prom_root_node, "mmu-nctx", 0x8); |
484 | */ | ||
485 | num_segmaps = 128; | ||
486 | num_contexts = 8; | ||
487 | } else { | ||
488 | num_segmaps = | ||
489 | prom_getintdefault(prom_root_node, "mmu-npmg", 128); | ||
490 | num_contexts = | ||
491 | prom_getintdefault(prom_root_node, "mmu-nctx", 0x8); | ||
492 | } | ||
493 | } | 414 | } |
494 | patch_kernel_fault_handler(); | 415 | patch_kernel_fault_handler(); |
495 | } | 416 | } |
@@ -501,18 +422,14 @@ void __init sun4c_probe_memerr_reg(void) | |||
501 | int node; | 422 | int node; |
502 | struct linux_prom_registers regs[1]; | 423 | struct linux_prom_registers regs[1]; |
503 | 424 | ||
504 | if (ARCH_SUN4) { | 425 | node = prom_getchild(prom_root_node); |
505 | sun4c_memerr_reg = ioremap(sun4_memreg_physaddr, PAGE_SIZE); | 426 | node = prom_searchsiblings(prom_root_node, "memory-error"); |
506 | } else { | 427 | if (!node) |
507 | node = prom_getchild(prom_root_node); | 428 | return; |
508 | node = prom_searchsiblings(prom_root_node, "memory-error"); | 429 | if (prom_getproperty(node, "reg", (char *)regs, sizeof(regs)) <= 0) |
509 | if (!node) | 430 | return; |
510 | return; | 431 | /* hmm I think regs[0].which_io is zero here anyways */ |
511 | if (prom_getproperty(node, "reg", (char *)regs, sizeof(regs)) <= 0) | 432 | sun4c_memerr_reg = ioremap(regs[0].phys_addr, regs[0].reg_size); |
512 | return; | ||
513 | /* hmm I think regs[0].which_io is zero here anyways */ | ||
514 | sun4c_memerr_reg = ioremap(regs[0].phys_addr, regs[0].reg_size); | ||
515 | } | ||
516 | } | 433 | } |
517 | 434 | ||
518 | static inline void sun4c_init_ss2_cache_bug(void) | 435 | static inline void sun4c_init_ss2_cache_bug(void) |
@@ -521,7 +438,6 @@ static inline void sun4c_init_ss2_cache_bug(void) | |||
521 | 438 | ||
522 | if ((idprom->id_machtype == (SM_SUN4C | SM_4C_SS2)) || | 439 | if ((idprom->id_machtype == (SM_SUN4C | SM_4C_SS2)) || |
523 | (idprom->id_machtype == (SM_SUN4C | SM_4C_IPX)) || | 440 | (idprom->id_machtype == (SM_SUN4C | SM_4C_IPX)) || |
524 | (idprom->id_machtype == (SM_SUN4 | SM_4_330)) || | ||
525 | (idprom->id_machtype == (SM_SUN4C | SM_4C_ELC))) { | 441 | (idprom->id_machtype == (SM_SUN4C | SM_4C_ELC))) { |
526 | /* Whee.. */ | 442 | /* Whee.. */ |
527 | printk("SS2 cache bug detected, uncaching trap table page\n"); | 443 | printk("SS2 cache bug detected, uncaching trap table page\n"); |
@@ -532,8 +448,8 @@ static inline void sun4c_init_ss2_cache_bug(void) | |||
532 | } | 448 | } |
533 | 449 | ||
534 | /* Addr is always aligned on a page boundary for us already. */ | 450 | /* Addr is always aligned on a page boundary for us already. */ |
535 | static int sun4c_map_dma_area(dma_addr_t *pba, unsigned long va, | 451 | static int sun4c_map_dma_area(struct device *dev, dma_addr_t *pba, unsigned long va, |
536 | unsigned long addr, int len) | 452 | unsigned long addr, int len) |
537 | { | 453 | { |
538 | unsigned long page, end; | 454 | unsigned long page, end; |
539 | 455 | ||
@@ -555,14 +471,7 @@ static int sun4c_map_dma_area(dma_addr_t *pba, unsigned long va, | |||
555 | return 0; | 471 | return 0; |
556 | } | 472 | } |
557 | 473 | ||
558 | static struct page *sun4c_translate_dvma(unsigned long busa) | 474 | static void sun4c_unmap_dma_area(struct device *dev, unsigned long busa, int len) |
559 | { | ||
560 | /* Fortunately for us, bus_addr == uncached_virt in sun4c. */ | ||
561 | unsigned long pte = sun4c_get_pte(busa); | ||
562 | return pfn_to_page(pte & SUN4C_PFN_MASK); | ||
563 | } | ||
564 | |||
565 | static void sun4c_unmap_dma_area(unsigned long busa, int len) | ||
566 | { | 475 | { |
567 | /* Fortunately for us, bus_addr == uncached_virt in sun4c. */ | 476 | /* Fortunately for us, bus_addr == uncached_virt in sun4c. */ |
568 | /* XXX Implement this */ | 477 | /* XXX Implement this */ |
@@ -624,11 +533,7 @@ static inline void sun4c_init_map_kernelprom(unsigned long kernel_end) | |||
624 | { | 533 | { |
625 | unsigned long vaddr; | 534 | unsigned long vaddr; |
626 | unsigned char pseg, ctx; | 535 | unsigned char pseg, ctx; |
627 | #ifdef CONFIG_SUN4 | 536 | |
628 | /* sun4/110 and 260 have no kadb. */ | ||
629 | if ((idprom->id_machtype != (SM_SUN4 | SM_4_260)) && | ||
630 | (idprom->id_machtype != (SM_SUN4 | SM_4_110))) { | ||
631 | #endif | ||
632 | for (vaddr = KADB_DEBUGGER_BEGVM; | 537 | for (vaddr = KADB_DEBUGGER_BEGVM; |
633 | vaddr < LINUX_OPPROM_ENDVM; | 538 | vaddr < LINUX_OPPROM_ENDVM; |
634 | vaddr += SUN4C_REAL_PGDIR_SIZE) { | 539 | vaddr += SUN4C_REAL_PGDIR_SIZE) { |
@@ -640,9 +545,7 @@ static inline void sun4c_init_map_kernelprom(unsigned long kernel_end) | |||
640 | fix_permissions(vaddr, _SUN4C_PAGE_PRIV, 0); | 545 | fix_permissions(vaddr, _SUN4C_PAGE_PRIV, 0); |
641 | } | 546 | } |
642 | } | 547 | } |
643 | #ifdef CONFIG_SUN4 | 548 | |
644 | } | ||
645 | #endif | ||
646 | for (vaddr = KERNBASE; vaddr < kernel_end; vaddr += SUN4C_REAL_PGDIR_SIZE) { | 549 | for (vaddr = KERNBASE; vaddr < kernel_end; vaddr += SUN4C_REAL_PGDIR_SIZE) { |
647 | pseg = sun4c_get_segmap(vaddr); | 550 | pseg = sun4c_get_segmap(vaddr); |
648 | mmu_entry_pool[pseg].locked = 1; | 551 | mmu_entry_pool[pseg].locked = 1; |
@@ -1048,14 +951,10 @@ static struct thread_info *sun4c_alloc_thread_info(void) | |||
1048 | * so we must flush the cache to guarantee consistency. | 951 | * so we must flush the cache to guarantee consistency. |
1049 | */ | 952 | */ |
1050 | sun4c_flush_page(pages); | 953 | sun4c_flush_page(pages); |
1051 | #ifndef CONFIG_SUN4 | ||
1052 | sun4c_flush_page(pages + PAGE_SIZE); | 954 | sun4c_flush_page(pages + PAGE_SIZE); |
1053 | #endif | ||
1054 | 955 | ||
1055 | sun4c_put_pte(addr, BUCKET_PTE(pages)); | 956 | sun4c_put_pte(addr, BUCKET_PTE(pages)); |
1056 | #ifndef CONFIG_SUN4 | ||
1057 | sun4c_put_pte(addr + PAGE_SIZE, BUCKET_PTE(pages + PAGE_SIZE)); | 957 | sun4c_put_pte(addr + PAGE_SIZE, BUCKET_PTE(pages + PAGE_SIZE)); |
1058 | #endif | ||
1059 | 958 | ||
1060 | #ifdef CONFIG_DEBUG_STACK_USAGE | 959 | #ifdef CONFIG_DEBUG_STACK_USAGE |
1061 | memset((void *)addr, 0, PAGE_SIZE << THREAD_INFO_ORDER); | 960 | memset((void *)addr, 0, PAGE_SIZE << THREAD_INFO_ORDER); |
@@ -1072,13 +971,11 @@ static void sun4c_free_thread_info(struct thread_info *ti) | |||
1072 | 971 | ||
1073 | /* We are deleting a mapping, so the flush here is mandatory. */ | 972 | /* We are deleting a mapping, so the flush here is mandatory. */ |
1074 | sun4c_flush_page(tiaddr); | 973 | sun4c_flush_page(tiaddr); |
1075 | #ifndef CONFIG_SUN4 | ||
1076 | sun4c_flush_page(tiaddr + PAGE_SIZE); | 974 | sun4c_flush_page(tiaddr + PAGE_SIZE); |
1077 | #endif | 975 | |
1078 | sun4c_put_pte(tiaddr, 0); | 976 | sun4c_put_pte(tiaddr, 0); |
1079 | #ifndef CONFIG_SUN4 | ||
1080 | sun4c_put_pte(tiaddr + PAGE_SIZE, 0); | 977 | sun4c_put_pte(tiaddr + PAGE_SIZE, 0); |
1081 | #endif | 978 | |
1082 | sun4c_bucket[entry] = BUCKET_EMPTY; | 979 | sun4c_bucket[entry] = BUCKET_EMPTY; |
1083 | if (entry < sun4c_lowbucket_avail) | 980 | if (entry < sun4c_lowbucket_avail) |
1084 | sun4c_lowbucket_avail = entry; | 981 | sun4c_lowbucket_avail = entry; |
@@ -1211,7 +1108,7 @@ static void sun4c_unlockarea(char *vaddr, unsigned long size) | |||
1211 | * by implication and fool the page locking code above | 1108 | * by implication and fool the page locking code above |
1212 | * if passed to by mistake. | 1109 | * if passed to by mistake. |
1213 | */ | 1110 | */ |
1214 | static __u32 sun4c_get_scsi_one(char *bufptr, unsigned long len, struct sbus_bus *sbus) | 1111 | static __u32 sun4c_get_scsi_one(struct device *dev, char *bufptr, unsigned long len) |
1215 | { | 1112 | { |
1216 | unsigned long page; | 1113 | unsigned long page; |
1217 | 1114 | ||
@@ -1223,7 +1120,7 @@ static __u32 sun4c_get_scsi_one(char *bufptr, unsigned long len, struct sbus_bus | |||
1223 | return (__u32)sun4c_lockarea(bufptr, len); | 1120 | return (__u32)sun4c_lockarea(bufptr, len); |
1224 | } | 1121 | } |
1225 | 1122 | ||
1226 | static void sun4c_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus *sbus) | 1123 | static void sun4c_get_scsi_sgl(struct device *dev, struct scatterlist *sg, int sz) |
1227 | { | 1124 | { |
1228 | while (sz != 0) { | 1125 | while (sz != 0) { |
1229 | --sz; | 1126 | --sz; |
@@ -1233,14 +1130,14 @@ static void sun4c_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus * | |||
1233 | } | 1130 | } |
1234 | } | 1131 | } |
1235 | 1132 | ||
1236 | static void sun4c_release_scsi_one(__u32 bufptr, unsigned long len, struct sbus_bus *sbus) | 1133 | static void sun4c_release_scsi_one(struct device *dev, __u32 bufptr, unsigned long len) |
1237 | { | 1134 | { |
1238 | if (bufptr < sun4c_iobuffer_start) | 1135 | if (bufptr < sun4c_iobuffer_start) |
1239 | return; /* On kernel stack or similar, see above */ | 1136 | return; /* On kernel stack or similar, see above */ |
1240 | sun4c_unlockarea((char *)bufptr, len); | 1137 | sun4c_unlockarea((char *)bufptr, len); |
1241 | } | 1138 | } |
1242 | 1139 | ||
1243 | static void sun4c_release_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus *sbus) | 1140 | static void sun4c_release_scsi_sgl(struct device *dev, struct scatterlist *sg, int sz) |
1244 | { | 1141 | { |
1245 | while (sz != 0) { | 1142 | while (sz != 0) { |
1246 | --sz; | 1143 | --sz; |
@@ -2263,7 +2160,6 @@ void __init ld_mmu_sun4c(void) | |||
2263 | 2160 | ||
2264 | BTFIXUPSET_CALL(mmu_map_dma_area, sun4c_map_dma_area, BTFIXUPCALL_NORM); | 2161 | BTFIXUPSET_CALL(mmu_map_dma_area, sun4c_map_dma_area, BTFIXUPCALL_NORM); |
2265 | BTFIXUPSET_CALL(mmu_unmap_dma_area, sun4c_unmap_dma_area, BTFIXUPCALL_NORM); | 2162 | BTFIXUPSET_CALL(mmu_unmap_dma_area, sun4c_unmap_dma_area, BTFIXUPCALL_NORM); |
2266 | BTFIXUPSET_CALL(mmu_translate_dvma, sun4c_translate_dvma, BTFIXUPCALL_NORM); | ||
2267 | 2163 | ||
2268 | BTFIXUPSET_CALL(sparc_mapiorange, sun4c_mapiorange, BTFIXUPCALL_NORM); | 2164 | BTFIXUPSET_CALL(sparc_mapiorange, sun4c_mapiorange, BTFIXUPCALL_NORM); |
2269 | BTFIXUPSET_CALL(sparc_unmapiorange, sun4c_unmapiorange, BTFIXUPCALL_NORM); | 2165 | BTFIXUPSET_CALL(sparc_unmapiorange, sun4c_unmapiorange, BTFIXUPCALL_NORM); |