X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fmips%2Fmm%2Fpg-r4k.c;h=b7c749232ffef80bb50c131f2853965aa7e72396;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=467fdfe2108cccf23da6aad0252b082c7d6a5cc0;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/arch/mips/mm/pg-r4k.c b/arch/mips/mm/pg-r4k.c index 467fdfe21..b7c749232 100644 --- a/arch/mips/mm/pg-r4k.c +++ b/arch/mips/mm/pg-r4k.c @@ -3,9 +3,8 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2003, 2004 Ralf Baechle (ralf@linux-mips.org) + * Copyright (C) 2003, 04, 05 Ralf Baechle (ralf@linux-mips.org) */ -#include #include #include #include @@ -26,7 +25,10 @@ #include #include -#define half_scache_line_size() (cpu_scache_line_size() >> 1) +#define half_scache_line_size() (cpu_scache_line_size() >> 1) +#define cpu_is_r4600_v1_x() ((read_c0_prid() & 0xfffffff0) == 0x00002010) +#define cpu_is_r4600_v2_x() ((read_c0_prid() & 0xfffffff0) == 0x00002020) + /* * Maximum sizes: @@ -57,12 +59,6 @@ void copy_page(void *to, void *from) __attribute__((alias("copy_page_array"))); EXPORT_SYMBOL(copy_page); -/* - * An address fits into a single register so it's safe to use 64-bit registers - * if we have 64-bit adresses. - */ -#define cpu_has_64bit_registers cpu_has_64bit_addresses - /* * This is suboptimal for 32-bit kernels; we assume that R10000 is only used * with 64-bit kernels. The prefetch offsets have been experimentally tuned @@ -128,7 +124,7 @@ static inline void build_nop(void) static inline void build_src_pref(int advance) { - if (!(load_offset & (cpu_dcache_line_size() - 1))) { + if (!(load_offset & (cpu_dcache_line_size() - 1)) && advance) { union mips_instruction mi; mi.i_format.opcode = pref_op; @@ -145,7 +141,7 @@ static inline void __build_load_reg(int reg) union mips_instruction mi; unsigned int width; - if (cpu_has_64bit_registers) { + if (cpu_has_64bit_gp_regs) { mi.i_format.opcode = ld_op; width = 8; } else { @@ -170,7 +166,7 @@ static inline void build_load_reg(int reg) static inline void build_dst_pref(int advance) { - if (!(store_offset & (cpu_dcache_line_size() - 1))) { + if (!(store_offset & (cpu_dcache_line_size() - 1)) && advance) { union mips_instruction mi; mi.i_format.opcode = pref_op; @@ -205,15 +201,15 @@ static inline void build_cdex_p(void) if (store_offset & (cpu_dcache_line_size() - 1)) return; - if (R4600_V1_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2010)) { + if (R4600_V1_HIT_CACHEOP_WAR && cpu_is_r4600_v1_x()) { build_nop(); build_nop(); build_nop(); build_nop(); } - if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020)) - build_insn_word(0x8c200000); /* lw $zero, ($at) */ + if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x()) + build_insn_word(0x3c01a000); /* lui $at, 0xa000 */ mi.c_format.opcode = cache_op; mi.c_format.rs = 4; /* $a0 */ @@ -224,7 +220,7 @@ static inline void build_cdex_p(void) emit_instruction(mi); } -static void __build_store_reg(int reg) +static void __init __build_store_reg(int reg) { union mips_instruction mi; unsigned int width; @@ -266,7 +262,7 @@ static inline void build_addiu_a2_a0(unsigned long offset) BUG_ON(offset > 0x7fff); - mi.i_format.opcode = cpu_has_64bit_addresses ? daddiu_op : addiu_op; + mi.i_format.opcode = cpu_has_64bit_gp_regs ? daddiu_op : addiu_op; mi.i_format.rs = 4; /* $a0 */ mi.i_format.rt = 6; /* $a2 */ mi.i_format.simmediate = offset; @@ -280,7 +276,7 @@ static inline void build_addiu_a1(unsigned long offset) BUG_ON(offset > 0x7fff); - mi.i_format.opcode = cpu_has_64bit_addresses ? daddiu_op : addiu_op; + mi.i_format.opcode = cpu_has_64bit_gp_regs ? daddiu_op : addiu_op; mi.i_format.rs = 5; /* $a1 */ mi.i_format.rt = 5; /* $a1 */ mi.i_format.simmediate = offset; @@ -296,7 +292,7 @@ static inline void build_addiu_a0(unsigned long offset) BUG_ON(offset > 0x7fff); - mi.i_format.opcode = cpu_has_64bit_addresses ? daddiu_op : addiu_op; + mi.i_format.opcode = cpu_has_64bit_gp_regs ? daddiu_op : addiu_op; mi.i_format.rs = 4; /* $a0 */ mi.i_format.rt = 4; /* $a0 */ mi.i_format.simmediate = offset; @@ -344,6 +340,12 @@ void __init build_clear_page(void) if (cpu_has_prefetch) { switch (current_cpu_data.cputype) { + case CPU_TX49XX: + /* TX49 supports only Pref_Load */ + pref_offset_clear = 0; + pref_offset_copy = 0; + break; + case CPU_RM9000: /* * As a workaround for erratum G105 which make the @@ -355,8 +357,9 @@ void __init build_clear_page(void) case CPU_R10000: case CPU_R12000: + case CPU_R14000: pref_src_mode = Pref_LoadStreamed; - pref_dst_mode = Pref_StoreRetained; + pref_dst_mode = Pref_StoreStreamed; break; default: @@ -368,7 +371,7 @@ void __init build_clear_page(void) build_addiu_a2_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_clear : 0)); - if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020)) + if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x()) build_insn_word(0x3c01a000); /* lui $at, 0xa000 */ dest = label(); @@ -411,9 +414,6 @@ dest = label(); build_jr_ra(); - flush_icache_range((unsigned long)&clear_page_array, - (unsigned long) epc); - BUG_ON(epc > clear_page_array + ARRAY_SIZE(clear_page_array)); } @@ -427,7 +427,7 @@ void __init build_copy_page(void) build_addiu_a2_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_copy : 0)); - if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020)) + if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x()) build_insn_word(0x3c01a000); /* lui $at, 0xa000 */ dest = label(); @@ -489,8 +489,5 @@ dest = label(); build_jr_ra(); - flush_icache_range((unsigned long)©_page_array, - (unsigned long) epc); - BUG_ON(epc > copy_page_array + ARRAY_SIZE(copy_page_array)); }