* for more details.
*
* Copyright (C) 2003, 04, 05 Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2007 Maciej W. Rozycki
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
+#include <asm/bugs.h>
#include <asm/cacheops.h>
#include <asm/inst.h>
#include <asm/io.h>
}
if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x())
- build_insn_word(0x3c01a000); /* lui $at, 0xa000 */
+ build_insn_word(0x8c200000); /* lw $zero, ($at) */
mi.c_format.opcode = cache_op;
mi.c_format.rs = 4; /* $a0 */
__build_store_reg(reg);
}
-static inline void build_addiu_a2_a0(unsigned long offset)
+static inline void build_addiu_rt_rs(unsigned int rt, unsigned int rs,
+ unsigned long offset)
{
union mips_instruction mi;
BUG_ON(offset > 0x7fff);
- 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;
+ if (cpu_has_64bit_gp_regs && DADDI_WAR && r4k_daddiu_bug()) {
+ mi.i_format.opcode = addiu_op;
+ mi.i_format.rs = 0; /* $zero */
+ mi.i_format.rt = 25; /* $t9 */
+ mi.i_format.simmediate = offset;
+ emit_instruction(mi);
+ mi.r_format.opcode = spec_op;
+ mi.r_format.rs = rs;
+ mi.r_format.rt = 25; /* $t9 */
+ mi.r_format.rd = rt;
+ mi.r_format.re = 0;
+ mi.r_format.func = daddu_op;
+ } else {
+ mi.i_format.opcode = cpu_has_64bit_gp_regs ?
+ daddiu_op : addiu_op;
+ mi.i_format.rs = rs;
+ mi.i_format.rt = rt;
+ mi.i_format.simmediate = offset;
+ }
emit_instruction(mi);
}
-static inline void build_addiu_a2(unsigned long offset)
+static inline void build_addiu_a2_a0(unsigned long offset)
{
- union mips_instruction mi;
-
- BUG_ON(offset > 0x7fff);
-
- mi.i_format.opcode = cpu_has_64bit_gp_regs ? daddiu_op : addiu_op;
- mi.i_format.rs = 6; /* $a2 */
- mi.i_format.rt = 6; /* $a2 */
- mi.i_format.simmediate = offset;
+ build_addiu_rt_rs(6, 4, offset); /* $a2, $a0, offset */
+}
- emit_instruction(mi);
+static inline void build_addiu_a2(unsigned long offset)
+{
+ build_addiu_rt_rs(6, 6, offset); /* $a2, $a2, offset */
}
static inline void build_addiu_a1(unsigned long offset)
{
- union mips_instruction mi;
-
- BUG_ON(offset > 0x7fff);
-
- 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;
+ build_addiu_rt_rs(5, 5, offset); /* $a1, $a1, offset */
load_offset -= offset;
-
- emit_instruction(mi);
}
static inline void build_addiu_a0(unsigned long offset)
{
- union mips_instruction mi;
-
- BUG_ON(offset > 0x7fff);
-
- 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;
+ build_addiu_rt_rs(4, 4, offset); /* $a0, $a0, offset */
store_offset -= offset;
-
- emit_instruction(mi);
}
static inline void build_bne(unsigned int *dest)
{
unsigned int loop_start;
unsigned long off;
+ int i;
epc = (unsigned int *) &clear_page_array;
instruction_pending = 0;
store_offset = 0;
if (cpu_has_prefetch) {
- switch (current_cpu_data.cputype) {
+ switch (current_cpu_type()) {
case CPU_TX49XX:
/* TX49 supports only Pref_Load */
pref_offset_clear = 0;
build_jr_ra();
BUG_ON(epc > clear_page_array + ARRAY_SIZE(clear_page_array));
+
+ pr_info("Synthesized clear page handler (%u instructions).\n",
+ (unsigned int)(epc - clear_page_array));
+
+ pr_debug("\t.set push\n");
+ pr_debug("\t.set noreorder\n");
+ for (i = 0; i < (epc - clear_page_array); i++)
+ pr_debug("\t.word 0x%08x\n", clear_page_array[i]);
+ pr_debug("\t.set pop\n");
}
void __init build_copy_page(void)
{
unsigned int loop_start;
unsigned long off;
+ int i;
epc = (unsigned int *) ©_page_array;
store_offset = load_offset = 0;
build_jr_ra();
BUG_ON(epc > copy_page_array + ARRAY_SIZE(copy_page_array));
+
+ pr_info("Synthesized copy page handler (%u instructions).\n",
+ (unsigned int)(epc - copy_page_array));
+
+ pr_debug("\t.set push\n");
+ pr_debug("\t.set noreorder\n");
+ for (i = 0; i < (epc - copy_page_array); i++)
+ pr_debug("\t.word 0x%08x\n", copy_page_array[i]);
+ pr_debug("\t.set pop\n");
}