diff options
Diffstat (limited to 'arch/sparc/mm/sun4c.c')
-rw-r--r-- | arch/sparc/mm/sun4c.c | 204 |
1 files changed, 50 insertions, 154 deletions
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); |