diff options
Diffstat (limited to 'arch/sparc/mm/sun4c.c')
-rw-r--r-- | arch/sparc/mm/sun4c.c | 182 |
1 files changed, 43 insertions, 139 deletions
diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c index f289e7ce902e..95070a1e1b7b 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"); |
@@ -617,11 +533,7 @@ static inline void sun4c_init_map_kernelprom(unsigned long kernel_end) | |||
617 | { | 533 | { |
618 | unsigned long vaddr; | 534 | unsigned long vaddr; |
619 | unsigned char pseg, ctx; | 535 | unsigned char pseg, ctx; |
620 | #ifdef CONFIG_SUN4 | 536 | |
621 | /* sun4/110 and 260 have no kadb. */ | ||
622 | if ((idprom->id_machtype != (SM_SUN4 | SM_4_260)) && | ||
623 | (idprom->id_machtype != (SM_SUN4 | SM_4_110))) { | ||
624 | #endif | ||
625 | for (vaddr = KADB_DEBUGGER_BEGVM; | 537 | for (vaddr = KADB_DEBUGGER_BEGVM; |
626 | vaddr < LINUX_OPPROM_ENDVM; | 538 | vaddr < LINUX_OPPROM_ENDVM; |
627 | vaddr += SUN4C_REAL_PGDIR_SIZE) { | 539 | vaddr += SUN4C_REAL_PGDIR_SIZE) { |
@@ -633,9 +545,7 @@ static inline void sun4c_init_map_kernelprom(unsigned long kernel_end) | |||
633 | fix_permissions(vaddr, _SUN4C_PAGE_PRIV, 0); | 545 | fix_permissions(vaddr, _SUN4C_PAGE_PRIV, 0); |
634 | } | 546 | } |
635 | } | 547 | } |
636 | #ifdef CONFIG_SUN4 | 548 | |
637 | } | ||
638 | #endif | ||
639 | for (vaddr = KERNBASE; vaddr < kernel_end; vaddr += SUN4C_REAL_PGDIR_SIZE) { | 549 | for (vaddr = KERNBASE; vaddr < kernel_end; vaddr += SUN4C_REAL_PGDIR_SIZE) { |
640 | pseg = sun4c_get_segmap(vaddr); | 550 | pseg = sun4c_get_segmap(vaddr); |
641 | mmu_entry_pool[pseg].locked = 1; | 551 | mmu_entry_pool[pseg].locked = 1; |
@@ -1041,14 +951,10 @@ static struct thread_info *sun4c_alloc_thread_info(void) | |||
1041 | * so we must flush the cache to guarantee consistency. | 951 | * so we must flush the cache to guarantee consistency. |
1042 | */ | 952 | */ |
1043 | sun4c_flush_page(pages); | 953 | sun4c_flush_page(pages); |
1044 | #ifndef CONFIG_SUN4 | ||
1045 | sun4c_flush_page(pages + PAGE_SIZE); | 954 | sun4c_flush_page(pages + PAGE_SIZE); |
1046 | #endif | ||
1047 | 955 | ||
1048 | sun4c_put_pte(addr, BUCKET_PTE(pages)); | 956 | sun4c_put_pte(addr, BUCKET_PTE(pages)); |
1049 | #ifndef CONFIG_SUN4 | ||
1050 | sun4c_put_pte(addr + PAGE_SIZE, BUCKET_PTE(pages + PAGE_SIZE)); | 957 | sun4c_put_pte(addr + PAGE_SIZE, BUCKET_PTE(pages + PAGE_SIZE)); |
1051 | #endif | ||
1052 | 958 | ||
1053 | #ifdef CONFIG_DEBUG_STACK_USAGE | 959 | #ifdef CONFIG_DEBUG_STACK_USAGE |
1054 | memset((void *)addr, 0, PAGE_SIZE << THREAD_INFO_ORDER); | 960 | memset((void *)addr, 0, PAGE_SIZE << THREAD_INFO_ORDER); |
@@ -1065,13 +971,11 @@ static void sun4c_free_thread_info(struct thread_info *ti) | |||
1065 | 971 | ||
1066 | /* We are deleting a mapping, so the flush here is mandatory. */ | 972 | /* We are deleting a mapping, so the flush here is mandatory. */ |
1067 | sun4c_flush_page(tiaddr); | 973 | sun4c_flush_page(tiaddr); |
1068 | #ifndef CONFIG_SUN4 | ||
1069 | sun4c_flush_page(tiaddr + PAGE_SIZE); | 974 | sun4c_flush_page(tiaddr + PAGE_SIZE); |
1070 | #endif | 975 | |
1071 | sun4c_put_pte(tiaddr, 0); | 976 | sun4c_put_pte(tiaddr, 0); |
1072 | #ifndef CONFIG_SUN4 | ||
1073 | sun4c_put_pte(tiaddr + PAGE_SIZE, 0); | 977 | sun4c_put_pte(tiaddr + PAGE_SIZE, 0); |
1074 | #endif | 978 | |
1075 | sun4c_bucket[entry] = BUCKET_EMPTY; | 979 | sun4c_bucket[entry] = BUCKET_EMPTY; |
1076 | if (entry < sun4c_lowbucket_avail) | 980 | if (entry < sun4c_lowbucket_avail) |
1077 | sun4c_lowbucket_avail = entry; | 981 | sun4c_lowbucket_avail = entry; |