* (no subject)
@ 2008-01-22 0:00 Thiemo Seufer
2008-01-28 17:51 ` your mail Ralf Baechle
0 siblings, 1 reply; 38+ messages in thread
From: Thiemo Seufer @ 2008-01-22 0:00 UTC (permalink / raw)
To: linux-mips; +Cc: ralf
Hello All,
This patch moves the micro-assembler in a separate implementation, as
it is useful for further run-time optimizations. The only change in
behaviour is cutting down printk noise at kernel startup time.
Checkpatch complains about macro parameters which aren't protected by
parentheses. I believe this is a flaw in checkpatch, the paste operator
used in those macros won't work with parenthesised parameters.
Tested on:
- Qemu 32-bit little endian
- BCM1480 64-bit big endian
Thiemo
---
Split the micro-assembler from tlbex.c.
Signed-off-by: Thiemo Seufer <ths@networkno.de>
diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile
index 32fd5db..c6f832e 100644
--- a/arch/mips/mm/Makefile
+++ b/arch/mips/mm/Makefile
@@ -3,7 +3,8 @@
#
obj-y += cache.o dma-default.o extable.o fault.o \
- init.o pgtable.o tlbex.o tlbex-fault.o
+ init.o pgtable.o tlbex.o tlbex-fault.o \
+ uasm.o
obj-$(CONFIG_32BIT) += ioremap.o pgtable-32.o
obj-$(CONFIG_64BIT) += pgtable-64.o
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index a61246d..48a2589 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -5,7 +5,7 @@
*
* Synthesize TLB refill handlers at runtime.
*
- * Copyright (C) 2004,2005,2006 by Thiemo Seufer
+ * Copyright (C) 2004,2005,2006,2008 Thiemo Seufer
* Copyright (C) 2005 Maciej W. Rozycki
* Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org)
*
@@ -19,8 +19,6 @@
* (Condolences to Napoleon XIV)
*/
-#include <stdarg.h>
-
#include <linux/mm.h>
#include <linux/kernel.h>
#include <linux/types.h>
@@ -30,11 +28,11 @@
#include <asm/pgtable.h>
#include <asm/cacheflush.h>
#include <asm/mmu_context.h>
-#include <asm/inst.h>
-#include <asm/elf.h>
#include <asm/smp.h>
#include <asm/war.h>
+#include "uasm.h"
+
static inline int r45k_bvahwbug(void)
{
/* XXX: We should probe for the presence of this bug, but we don't. */
@@ -72,371 +70,9 @@ static __init int __attribute__((unused)) m4kc_tlbp_war(void)
(PRID_COMP_MIPS | PRID_IMP_4KC);
}
-/*
- * A little micro-assembler, intended for TLB refill handler
- * synthesizing. It is intentionally kept simple, does only support
- * a subset of instructions, and does not try to hide pipeline effects
- * like branch delay slots.
- */
-
-enum fields
-{
- RS = 0x001,
- RT = 0x002,
- RD = 0x004,
- RE = 0x008,
- SIMM = 0x010,
- UIMM = 0x020,
- BIMM = 0x040,
- JIMM = 0x080,
- FUNC = 0x100,
- SET = 0x200
-};
-
-#define OP_MASK 0x3f
-#define OP_SH 26
-#define RS_MASK 0x1f
-#define RS_SH 21
-#define RT_MASK 0x1f
-#define RT_SH 16
-#define RD_MASK 0x1f
-#define RD_SH 11
-#define RE_MASK 0x1f
-#define RE_SH 6
-#define IMM_MASK 0xffff
-#define IMM_SH 0
-#define JIMM_MASK 0x3ffffff
-#define JIMM_SH 0
-#define FUNC_MASK 0x3f
-#define FUNC_SH 0
-#define SET_MASK 0x7
-#define SET_SH 0
-
-enum opcode {
- insn_invalid,
- insn_addu, insn_addiu, insn_and, insn_andi, insn_beq,
- insn_beql, insn_bgez, insn_bgezl, insn_bltz, insn_bltzl,
- insn_bne, insn_daddu, insn_daddiu, insn_dmfc0, insn_dmtc0,
- insn_dsll, insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32,
- insn_dsubu, insn_eret, insn_j, insn_jal, insn_jr, insn_ld,
- insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0, insn_mtc0,
- insn_ori, insn_rfe, insn_sc, insn_scd, insn_sd, insn_sll,
- insn_sra, insn_srl, insn_subu, insn_sw, insn_tlbp, insn_tlbwi,
- insn_tlbwr, insn_xor, insn_xori
-};
-
-struct insn {
- enum opcode opcode;
- u32 match;
- enum fields fields;
-};
-
-/* This macro sets the non-variable bits of an instruction. */
-#define M(a, b, c, d, e, f) \
- ((a) << OP_SH \
- | (b) << RS_SH \
- | (c) << RT_SH \
- | (d) << RD_SH \
- | (e) << RE_SH \
- | (f) << FUNC_SH)
-
-static __initdata struct insn insn_table[] = {
- { insn_addiu, M(addiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
- { insn_addu, M(spec_op, 0, 0, 0, 0, addu_op), RS | RT | RD },
- { insn_and, M(spec_op, 0, 0, 0, 0, and_op), RS | RT | RD },
- { insn_andi, M(andi_op, 0, 0, 0, 0, 0), RS | RT | UIMM },
- { insn_beq, M(beq_op, 0, 0, 0, 0, 0), RS | RT | BIMM },
- { insn_beql, M(beql_op, 0, 0, 0, 0, 0), RS | RT | BIMM },
- { insn_bgez, M(bcond_op, 0, bgez_op, 0, 0, 0), RS | BIMM },
- { insn_bgezl, M(bcond_op, 0, bgezl_op, 0, 0, 0), RS | BIMM },
- { insn_bltz, M(bcond_op, 0, bltz_op, 0, 0, 0), RS | BIMM },
- { insn_bltzl, M(bcond_op, 0, bltzl_op, 0, 0, 0), RS | BIMM },
- { insn_bne, M(bne_op, 0, 0, 0, 0, 0), RS | RT | BIMM },
- { insn_daddiu, M(daddiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
- { insn_daddu, M(spec_op, 0, 0, 0, 0, daddu_op), RS | RT | RD },
- { insn_dmfc0, M(cop0_op, dmfc_op, 0, 0, 0, 0), RT | RD | SET},
- { insn_dmtc0, M(cop0_op, dmtc_op, 0, 0, 0, 0), RT | RD | SET},
- { insn_dsll, M(spec_op, 0, 0, 0, 0, dsll_op), RT | RD | RE },
- { insn_dsll32, M(spec_op, 0, 0, 0, 0, dsll32_op), RT | RD | RE },
- { insn_dsra, M(spec_op, 0, 0, 0, 0, dsra_op), RT | RD | RE },
- { insn_dsrl, M(spec_op, 0, 0, 0, 0, dsrl_op), RT | RD | RE },
- { insn_dsrl32, M(spec_op, 0, 0, 0, 0, dsrl32_op), RT | RD | RE },
- { insn_dsubu, M(spec_op, 0, 0, 0, 0, dsubu_op), RS | RT | RD },
- { insn_eret, M(cop0_op, cop_op, 0, 0, 0, eret_op), 0 },
- { insn_j, M(j_op, 0, 0, 0, 0, 0), JIMM },
- { insn_jal, M(jal_op, 0, 0, 0, 0, 0), JIMM },
- { insn_jr, M(spec_op, 0, 0, 0, 0, jr_op), RS },
- { insn_ld, M(ld_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
- { insn_ll, M(ll_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
- { insn_lld, M(lld_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
- { insn_lui, M(lui_op, 0, 0, 0, 0, 0), RT | SIMM },
- { insn_lw, M(lw_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
- { insn_mfc0, M(cop0_op, mfc_op, 0, 0, 0, 0), RT | RD | SET},
- { insn_mtc0, M(cop0_op, mtc_op, 0, 0, 0, 0), RT | RD | SET},
- { insn_ori, M(ori_op, 0, 0, 0, 0, 0), RS | RT | UIMM },
- { insn_rfe, M(cop0_op, cop_op, 0, 0, 0, rfe_op), 0 },
- { insn_sc, M(sc_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
- { insn_scd, M(scd_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
- { insn_sd, M(sd_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
- { insn_sll, M(spec_op, 0, 0, 0, 0, sll_op), RT | RD | RE },
- { insn_sra, M(spec_op, 0, 0, 0, 0, sra_op), RT | RD | RE },
- { insn_srl, M(spec_op, 0, 0, 0, 0, srl_op), RT | RD | RE },
- { insn_subu, M(spec_op, 0, 0, 0, 0, subu_op), RS | RT | RD },
- { insn_sw, M(sw_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
- { insn_tlbp, M(cop0_op, cop_op, 0, 0, 0, tlbp_op), 0 },
- { insn_tlbwi, M(cop0_op, cop_op, 0, 0, 0, tlbwi_op), 0 },
- { insn_tlbwr, M(cop0_op, cop_op, 0, 0, 0, tlbwr_op), 0 },
- { insn_xor, M(spec_op, 0, 0, 0, 0, xor_op), RS | RT | RD },
- { insn_xori, M(xori_op, 0, 0, 0, 0, 0), RS | RT | UIMM },
- { insn_invalid, 0, 0 }
-};
-
-#undef M
-
-static __init u32 build_rs(u32 arg)
-{
- if (arg & ~RS_MASK)
- printk(KERN_WARNING "TLB synthesizer field overflow\n");
-
- return (arg & RS_MASK) << RS_SH;
-}
-
-static __init u32 build_rt(u32 arg)
-{
- if (arg & ~RT_MASK)
- printk(KERN_WARNING "TLB synthesizer field overflow\n");
-
- return (arg & RT_MASK) << RT_SH;
-}
-
-static __init u32 build_rd(u32 arg)
-{
- if (arg & ~RD_MASK)
- printk(KERN_WARNING "TLB synthesizer field overflow\n");
-
- return (arg & RD_MASK) << RD_SH;
-}
-
-static __init u32 build_re(u32 arg)
-{
- if (arg & ~RE_MASK)
- printk(KERN_WARNING "TLB synthesizer field overflow\n");
-
- return (arg & RE_MASK) << RE_SH;
-}
-
-static __init u32 build_simm(s32 arg)
-{
- if (arg > 0x7fff || arg < -0x8000)
- printk(KERN_WARNING "TLB synthesizer field overflow\n");
-
- return arg & 0xffff;
-}
-
-static __init u32 build_uimm(u32 arg)
-{
- if (arg & ~IMM_MASK)
- printk(KERN_WARNING "TLB synthesizer field overflow\n");
-
- return arg & IMM_MASK;
-}
-
-static __init u32 build_bimm(s32 arg)
-{
- if (arg > 0x1ffff || arg < -0x20000)
- printk(KERN_WARNING "TLB synthesizer field overflow\n");
-
- if (arg & 0x3)
- printk(KERN_WARNING "Invalid TLB synthesizer branch target\n");
-
- return ((arg < 0) ? (1 << 15) : 0) | ((arg >> 2) & 0x7fff);
-}
-
-static __init u32 build_jimm(u32 arg)
-{
- if (arg & ~((JIMM_MASK) << 2))
- printk(KERN_WARNING "TLB synthesizer field overflow\n");
-
- return (arg >> 2) & JIMM_MASK;
-}
-
-static __init u32 build_func(u32 arg)
-{
- if (arg & ~FUNC_MASK)
- printk(KERN_WARNING "TLB synthesizer field overflow\n");
-
- return arg & FUNC_MASK;
-}
-
-static __init u32 build_set(u32 arg)
-{
- if (arg & ~SET_MASK)
- printk(KERN_WARNING "TLB synthesizer field overflow\n");
-
- return arg & SET_MASK;
-}
-
-/*
- * The order of opcode arguments is implicitly left to right,
- * starting with RS and ending with FUNC or IMM.
- */
-static void __init build_insn(u32 **buf, enum opcode opc, ...)
-{
- struct insn *ip = NULL;
- unsigned int i;
- va_list ap;
- u32 op;
-
- for (i = 0; insn_table[i].opcode != insn_invalid; i++)
- if (insn_table[i].opcode == opc) {
- ip = &insn_table[i];
- break;
- }
-
- if (!ip)
- panic("Unsupported TLB synthesizer instruction %d", opc);
-
- op = ip->match;
- va_start(ap, opc);
- if (ip->fields & RS) op |= build_rs(va_arg(ap, u32));
- if (ip->fields & RT) op |= build_rt(va_arg(ap, u32));
- if (ip->fields & RD) op |= build_rd(va_arg(ap, u32));
- if (ip->fields & RE) op |= build_re(va_arg(ap, u32));
- if (ip->fields & SIMM) op |= build_simm(va_arg(ap, s32));
- if (ip->fields & UIMM) op |= build_uimm(va_arg(ap, u32));
- if (ip->fields & BIMM) op |= build_bimm(va_arg(ap, s32));
- if (ip->fields & JIMM) op |= build_jimm(va_arg(ap, u32));
- if (ip->fields & FUNC) op |= build_func(va_arg(ap, u32));
- if (ip->fields & SET) op |= build_set(va_arg(ap, u32));
- va_end(ap);
-
- **buf = op;
- (*buf)++;
-}
-
-#define I_u1u2u3(op) \
- static inline void __init i##op(u32 **buf, unsigned int a, \
- unsigned int b, unsigned int c) \
- { \
- build_insn(buf, insn##op, a, b, c); \
- }
-
-#define I_u2u1u3(op) \
- static inline void __init i##op(u32 **buf, unsigned int a, \
- unsigned int b, unsigned int c) \
- { \
- build_insn(buf, insn##op, b, a, c); \
- }
-
-#define I_u3u1u2(op) \
- static inline void __init i##op(u32 **buf, unsigned int a, \
- unsigned int b, unsigned int c) \
- { \
- build_insn(buf, insn##op, b, c, a); \
- }
-
-#define I_u1u2s3(op) \
- static inline void __init i##op(u32 **buf, unsigned int a, \
- unsigned int b, signed int c) \
- { \
- build_insn(buf, insn##op, a, b, c); \
- }
-
-#define I_u2s3u1(op) \
- static inline void __init i##op(u32 **buf, unsigned int a, \
- signed int b, unsigned int c) \
- { \
- build_insn(buf, insn##op, c, a, b); \
- }
-
-#define I_u2u1s3(op) \
- static inline void __init i##op(u32 **buf, unsigned int a, \
- unsigned int b, signed int c) \
- { \
- build_insn(buf, insn##op, b, a, c); \
- }
-
-#define I_u1u2(op) \
- static inline void __init i##op(u32 **buf, unsigned int a, \
- unsigned int b) \
- { \
- build_insn(buf, insn##op, a, b); \
- }
-
-#define I_u1s2(op) \
- static inline void __init i##op(u32 **buf, unsigned int a, \
- signed int b) \
- { \
- build_insn(buf, insn##op, a, b); \
- }
-
-#define I_u1(op) \
- static inline void __init i##op(u32 **buf, unsigned int a) \
- { \
- build_insn(buf, insn##op, a); \
- }
-
-#define I_0(op) \
- static inline void __init i##op(u32 **buf) \
- { \
- build_insn(buf, insn##op); \
- }
-
-I_u2u1s3(_addiu);
-I_u3u1u2(_addu);
-I_u2u1u3(_andi);
-I_u3u1u2(_and);
-I_u1u2s3(_beq);
-I_u1u2s3(_beql);
-I_u1s2(_bgez);
-I_u1s2(_bgezl);
-I_u1s2(_bltz);
-I_u1s2(_bltzl);
-I_u1u2s3(_bne);
-I_u1u2u3(_dmfc0);
-I_u1u2u3(_dmtc0);
-I_u2u1s3(_daddiu);
-I_u3u1u2(_daddu);
-I_u2u1u3(_dsll);
-I_u2u1u3(_dsll32);
-I_u2u1u3(_dsra);
-I_u2u1u3(_dsrl);
-I_u2u1u3(_dsrl32);
-I_u3u1u2(_dsubu);
-I_0(_eret);
-I_u1(_j);
-I_u1(_jal);
-I_u1(_jr);
-I_u2s3u1(_ld);
-I_u2s3u1(_ll);
-I_u2s3u1(_lld);
-I_u1s2(_lui);
-I_u2s3u1(_lw);
-I_u1u2u3(_mfc0);
-I_u1u2u3(_mtc0);
-I_u2u1u3(_ori);
-I_0(_rfe);
-I_u2s3u1(_sc);
-I_u2s3u1(_scd);
-I_u2s3u1(_sd);
-I_u2u1u3(_sll);
-I_u2u1u3(_sra);
-I_u2u1u3(_srl);
-I_u3u1u2(_subu);
-I_u2s3u1(_sw);
-I_0(_tlbp);
-I_0(_tlbwi);
-I_0(_tlbwr);
-I_u3u1u2(_xor)
-I_u2u1u3(_xori);
-
-/*
- * handling labels
- */
-
+/* Handle labels (which must be positive integers). */
enum label_id {
- label_invalid,
- label_second_part,
+ label_second_part = 1,
label_leave,
#ifdef MODULE_START
label_module_alloc,
@@ -452,267 +88,20 @@ enum label_id {
label_r3000_write_probe_fail,
};
-struct label {
- u32 *addr;
- enum label_id lab;
-};
-
-static __init void build_label(struct label **lab, u32 *addr,
- enum label_id l)
-{
- (*lab)->addr = addr;
- (*lab)->lab = l;
- (*lab)++;
-}
-
-#define L_LA(lb) \
- static inline void l##lb(struct label **lab, u32 *addr) \
- { \
- build_label(lab, addr, label##lb); \
- }
-
-L_LA(_second_part)
-L_LA(_leave)
+UASM_L_LA(_second_part)
+UASM_L_LA(_leave)
#ifdef MODULE_START
-L_LA(_module_alloc)
-#endif
-L_LA(_vmalloc)
-L_LA(_vmalloc_done)
-L_LA(_tlbw_hazard)
-L_LA(_split)
-L_LA(_nopage_tlbl)
-L_LA(_nopage_tlbs)
-L_LA(_nopage_tlbm)
-L_LA(_smp_pgtable_change)
-L_LA(_r3000_write_probe_fail)
-
-/* convenience macros for instructions */
-#ifdef CONFIG_64BIT
-# define i_LW(buf, rs, rt, off) i_ld(buf, rs, rt, off)
-# define i_SW(buf, rs, rt, off) i_sd(buf, rs, rt, off)
-# define i_SLL(buf, rs, rt, sh) i_dsll(buf, rs, rt, sh)
-# define i_SRA(buf, rs, rt, sh) i_dsra(buf, rs, rt, sh)
-# define i_SRL(buf, rs, rt, sh) i_dsrl(buf, rs, rt, sh)
-# define i_MFC0(buf, rt, rd...) i_dmfc0(buf, rt, rd)
-# define i_MTC0(buf, rt, rd...) i_dmtc0(buf, rt, rd)
-# define i_ADDIU(buf, rs, rt, val) i_daddiu(buf, rs, rt, val)
-# define i_ADDU(buf, rs, rt, rd) i_daddu(buf, rs, rt, rd)
-# define i_SUBU(buf, rs, rt, rd) i_dsubu(buf, rs, rt, rd)
-# define i_LL(buf, rs, rt, off) i_lld(buf, rs, rt, off)
-# define i_SC(buf, rs, rt, off) i_scd(buf, rs, rt, off)
-#else
-# define i_LW(buf, rs, rt, off) i_lw(buf, rs, rt, off)
-# define i_SW(buf, rs, rt, off) i_sw(buf, rs, rt, off)
-# define i_SLL(buf, rs, rt, sh) i_sll(buf, rs, rt, sh)
-# define i_SRA(buf, rs, rt, sh) i_sra(buf, rs, rt, sh)
-# define i_SRL(buf, rs, rt, sh) i_srl(buf, rs, rt, sh)
-# define i_MFC0(buf, rt, rd...) i_mfc0(buf, rt, rd)
-# define i_MTC0(buf, rt, rd...) i_mtc0(buf, rt, rd)
-# define i_ADDIU(buf, rs, rt, val) i_addiu(buf, rs, rt, val)
-# define i_ADDU(buf, rs, rt, rd) i_addu(buf, rs, rt, rd)
-# define i_SUBU(buf, rs, rt, rd) i_subu(buf, rs, rt, rd)
-# define i_LL(buf, rs, rt, off) i_ll(buf, rs, rt, off)
-# define i_SC(buf, rs, rt, off) i_sc(buf, rs, rt, off)
-#endif
-
-#define i_b(buf, off) i_beq(buf, 0, 0, off)
-#define i_beqz(buf, rs, off) i_beq(buf, rs, 0, off)
-#define i_beqzl(buf, rs, off) i_beql(buf, rs, 0, off)
-#define i_bnez(buf, rs, off) i_bne(buf, rs, 0, off)
-#define i_bnezl(buf, rs, off) i_bnel(buf, rs, 0, off)
-#define i_move(buf, a, b) i_ADDU(buf, a, 0, b)
-#define i_nop(buf) i_sll(buf, 0, 0, 0)
-#define i_ssnop(buf) i_sll(buf, 0, 0, 1)
-#define i_ehb(buf) i_sll(buf, 0, 0, 3)
-
-#ifdef CONFIG_64BIT
-static __init int __maybe_unused in_compat_space_p(long addr)
-{
- /* Is this address in 32bit compat space? */
- return (((addr) & 0xffffffff00000000L) == 0xffffffff00000000L);
-}
-
-static __init int __maybe_unused rel_highest(long val)
-{
- return ((((val + 0x800080008000L) >> 48) & 0xffff) ^ 0x8000) - 0x8000;
-}
-
-static __init int __maybe_unused rel_higher(long val)
-{
- return ((((val + 0x80008000L) >> 32) & 0xffff) ^ 0x8000) - 0x8000;
-}
-#endif
-
-static __init int rel_hi(long val)
-{
- return ((((val + 0x8000L) >> 16) & 0xffff) ^ 0x8000) - 0x8000;
-}
-
-static __init int rel_lo(long val)
-{
- return ((val & 0xffff) ^ 0x8000) - 0x8000;
-}
-
-static __init void i_LA_mostly(u32 **buf, unsigned int rs, long addr)
-{
-#ifdef CONFIG_64BIT
- if (!in_compat_space_p(addr)) {
- i_lui(buf, rs, rel_highest(addr));
- if (rel_higher(addr))
- i_daddiu(buf, rs, rs, rel_higher(addr));
- if (rel_hi(addr)) {
- i_dsll(buf, rs, rs, 16);
- i_daddiu(buf, rs, rs, rel_hi(addr));
- i_dsll(buf, rs, rs, 16);
- } else
- i_dsll32(buf, rs, rs, 0);
- } else
+UASM_L_LA(_module_alloc)
#endif
- i_lui(buf, rs, rel_hi(addr));
-}
-
-static __init void __maybe_unused i_LA(u32 **buf, unsigned int rs,
- long addr)
-{
- i_LA_mostly(buf, rs, addr);
- if (rel_lo(addr))
- i_ADDIU(buf, rs, rs, rel_lo(addr));
-}
-
-/*
- * handle relocations
- */
-
-struct reloc {
- u32 *addr;
- unsigned int type;
- enum label_id lab;
-};
-
-static __init void r_mips_pc16(struct reloc **rel, u32 *addr,
- enum label_id l)
-{
- (*rel)->addr = addr;
- (*rel)->type = R_MIPS_PC16;
- (*rel)->lab = l;
- (*rel)++;
-}
-
-static inline void __resolve_relocs(struct reloc *rel, struct label *lab)
-{
- long laddr = (long)lab->addr;
- long raddr = (long)rel->addr;
-
- switch (rel->type) {
- case R_MIPS_PC16:
- *rel->addr |= build_bimm(laddr - (raddr + 4));
- break;
-
- default:
- panic("Unsupported TLB synthesizer relocation %d",
- rel->type);
- }
-}
-
-static __init void resolve_relocs(struct reloc *rel, struct label *lab)
-{
- struct label *l;
-
- for (; rel->lab != label_invalid; rel++)
- for (l = lab; l->lab != label_invalid; l++)
- if (rel->lab == l->lab)
- __resolve_relocs(rel, l);
-}
-
-static __init void move_relocs(struct reloc *rel, u32 *first, u32 *end,
- long off)
-{
- for (; rel->lab != label_invalid; rel++)
- if (rel->addr >= first && rel->addr < end)
- rel->addr += off;
-}
-
-static __init void move_labels(struct label *lab, u32 *first, u32 *end,
- long off)
-{
- for (; lab->lab != label_invalid; lab++)
- if (lab->addr >= first && lab->addr < end)
- lab->addr += off;
-}
-
-static __init void copy_handler(struct reloc *rel, struct label *lab,
- u32 *first, u32 *end, u32 *target)
-{
- long off = (long)(target - first);
-
- memcpy(target, first, (end - first) * sizeof(u32));
-
- move_relocs(rel, first, end, off);
- move_labels(lab, first, end, off);
-}
-
-static __init int __maybe_unused insn_has_bdelay(struct reloc *rel,
- u32 *addr)
-{
- for (; rel->lab != label_invalid; rel++) {
- if (rel->addr == addr
- && (rel->type == R_MIPS_PC16
- || rel->type == R_MIPS_26))
- return 1;
- }
-
- return 0;
-}
-
-/* convenience functions for labeled branches */
-static void __init __maybe_unused
- il_bltz(u32 **p, struct reloc **r, unsigned int reg, enum label_id l)
-{
- r_mips_pc16(r, *p, l);
- i_bltz(p, reg, 0);
-}
-
-static void __init __maybe_unused il_b(u32 **p, struct reloc **r,
- enum label_id l)
-{
- r_mips_pc16(r, *p, l);
- i_b(p, 0);
-}
-
-static void __init il_beqz(u32 **p, struct reloc **r, unsigned int reg,
- enum label_id l)
-{
- r_mips_pc16(r, *p, l);
- i_beqz(p, reg, 0);
-}
-
-static void __init __maybe_unused
-il_beqzl(u32 **p, struct reloc **r, unsigned int reg, enum label_id l)
-{
- r_mips_pc16(r, *p, l);
- i_beqzl(p, reg, 0);
-}
-
-static void __init il_bnez(u32 **p, struct reloc **r, unsigned int reg,
- enum label_id l)
-{
- r_mips_pc16(r, *p, l);
- i_bnez(p, reg, 0);
-}
-
-static void __init il_bgezl(u32 **p, struct reloc **r, unsigned int reg,
- enum label_id l)
-{
- r_mips_pc16(r, *p, l);
- i_bgezl(p, reg, 0);
-}
-
-static void __init __maybe_unused
-il_bgez(u32 **p, struct reloc **r, unsigned int reg, enum label_id l)
-{
- r_mips_pc16(r, *p, l);
- i_bgez(p, reg, 0);
-}
+UASM_L_LA(_vmalloc)
+UASM_L_LA(_vmalloc_done)
+UASM_L_LA(_tlbw_hazard)
+UASM_L_LA(_split)
+UASM_L_LA(_nopage_tlbl)
+UASM_L_LA(_nopage_tlbs)
+UASM_L_LA(_nopage_tlbm)
+UASM_L_LA(_smp_pgtable_change)
+UASM_L_LA(_r3000_write_probe_fail)
/* The only general purpose registers allowed in TLB handlers. */
#define K0 26
@@ -730,9 +119,9 @@ il_bgez(u32 **p, struct reloc **r, unsigned int reg, enum label_id l)
#define C0_XCONTEXT 20, 0
#ifdef CONFIG_64BIT
-# define GET_CONTEXT(buf, reg) i_MFC0(buf, reg, C0_XCONTEXT)
+# define GET_CONTEXT(buf, reg) UASM_i_MFC0(buf, reg, C0_XCONTEXT)
#else
-# define GET_CONTEXT(buf, reg) i_MFC0(buf, reg, C0_CONTEXT)
+# define GET_CONTEXT(buf, reg) UASM_i_MFC0(buf, reg, C0_CONTEXT)
#endif
/* The worst case length of the handler is around 18 instructions for
@@ -746,8 +135,8 @@ il_bgez(u32 **p, struct reloc **r, unsigned int reg, enum label_id l)
static __initdata u32 tlb_handler[128];
/* simply assume worst case size for labels and relocs */
-static __initdata struct label labels[128];
-static __initdata struct reloc relocs[128];
+static __initdata struct uasm_label labels[128];
+static __initdata struct uasm_reloc relocs[128];
/*
* The R3000 TLB handler is simple.
@@ -761,29 +150,29 @@ static void __init build_r3000_tlb_refill_handler(void)
memset(tlb_handler, 0, sizeof(tlb_handler));
p = tlb_handler;
- i_mfc0(&p, K0, C0_BADVADDR);
- i_lui(&p, K1, rel_hi(pgdc)); /* cp0 delay */
- i_lw(&p, K1, rel_lo(pgdc), K1);
- i_srl(&p, K0, K0, 22); /* load delay */
- i_sll(&p, K0, K0, 2);
- i_addu(&p, K1, K1, K0);
- i_mfc0(&p, K0, C0_CONTEXT);
- i_lw(&p, K1, 0, K1); /* cp0 delay */
- i_andi(&p, K0, K0, 0xffc); /* load delay */
- i_addu(&p, K1, K1, K0);
- i_lw(&p, K0, 0, K1);
- i_nop(&p); /* load delay */
- i_mtc0(&p, K0, C0_ENTRYLO0);
- i_mfc0(&p, K1, C0_EPC); /* cp0 delay */
- i_tlbwr(&p); /* cp0 delay */
- i_jr(&p, K1);
- i_rfe(&p); /* branch delay */
+ uasm_i_mfc0(&p, K0, C0_BADVADDR);
+ uasm_i_lui(&p, K1, uasm_rel_hi(pgdc)); /* cp0 delay */
+ uasm_i_lw(&p, K1, uasm_rel_lo(pgdc), K1);
+ uasm_i_srl(&p, K0, K0, 22); /* load delay */
+ uasm_i_sll(&p, K0, K0, 2);
+ uasm_i_addu(&p, K1, K1, K0);
+ uasm_i_mfc0(&p, K0, C0_CONTEXT);
+ uasm_i_lw(&p, K1, 0, K1); /* cp0 delay */
+ uasm_i_andi(&p, K0, K0, 0xffc); /* load delay */
+ uasm_i_addu(&p, K1, K1, K0);
+ uasm_i_lw(&p, K0, 0, K1);
+ uasm_i_nop(&p); /* load delay */
+ uasm_i_mtc0(&p, K0, C0_ENTRYLO0);
+ uasm_i_mfc0(&p, K1, C0_EPC); /* cp0 delay */
+ uasm_i_tlbwr(&p); /* cp0 delay */
+ uasm_i_jr(&p, K1);
+ uasm_i_rfe(&p); /* branch delay */
if (p > tlb_handler + 32)
panic("TLB refill handler space exceeded");
- pr_info("Synthesized TLB refill handler (%u instructions).\n",
- (unsigned int)(p - tlb_handler));
+ pr_debug("Wrote TLB refill handler (%u instructions).\n",
+ (unsigned int)(p - tlb_handler));
pr_debug("\t.set push\n");
pr_debug("\t.set noreorder\n");
@@ -833,12 +222,12 @@ static __init void __maybe_unused build_tlb_probe_entry(u32 **p)
case CPU_R5000:
case CPU_R5000A:
case CPU_NEVADA:
- i_nop(p);
- i_tlbp(p);
+ uasm_i_nop(p);
+ uasm_i_tlbp(p);
break;
default:
- i_tlbp(p);
+ uasm_i_tlbp(p);
break;
}
}
@@ -849,15 +238,15 @@ static __init void __maybe_unused build_tlb_probe_entry(u32 **p)
*/
enum tlb_write_entry { tlb_random, tlb_indexed };
-static __init void build_tlb_write_entry(u32 **p, struct label **l,
- struct reloc **r,
+static __init void build_tlb_write_entry(u32 **p, struct uasm_label **l,
+ struct uasm_reloc **r,
enum tlb_write_entry wmode)
{
void(*tlbw)(u32 **) = NULL;
switch (wmode) {
- case tlb_random: tlbw = i_tlbwr; break;
- case tlb_indexed: tlbw = i_tlbwi; break;
+ case tlb_random: tlbw = uasm_i_tlbwr; break;
+ case tlb_indexed: tlbw = uasm_i_tlbwi; break;
}
switch (current_cpu_type()) {
@@ -871,19 +260,19 @@ static __init void build_tlb_write_entry(u32 **p, struct label **l,
* This branch uses up a mtc0 hazard nop slot and saves
* two nops after the tlbw instruction.
*/
- il_bgezl(p, r, 0, label_tlbw_hazard);
+ uasm_il_bgezl(p, r, 0, label_tlbw_hazard);
tlbw(p);
- l_tlbw_hazard(l, *p);
- i_nop(p);
+ uasm_l_tlbw_hazard(l, *p);
+ uasm_i_nop(p);
break;
case CPU_R4600:
case CPU_R4700:
case CPU_R5000:
case CPU_R5000A:
- i_nop(p);
+ uasm_i_nop(p);
tlbw(p);
- i_nop(p);
+ uasm_i_nop(p);
break;
case CPU_R4300:
@@ -895,7 +284,7 @@ static __init void build_tlb_write_entry(u32 **p, struct label **l,
case CPU_AU1550:
case CPU_AU1200:
case CPU_PR4450:
- i_nop(p);
+ uasm_i_nop(p);
tlbw(p);
break;
@@ -912,26 +301,26 @@ static __init void build_tlb_write_entry(u32 **p, struct label **l,
case CPU_BCM4710:
case CPU_LOONGSON2:
if (m4kc_tlbp_war())
- i_nop(p);
+ uasm_i_nop(p);
tlbw(p);
break;
case CPU_NEVADA:
- i_nop(p); /* QED specifies 2 nops hazard */
+ uasm_i_nop(p); /* QED specifies 2 nops hazard */
/*
* This branch uses up a mtc0 hazard nop slot and saves
* a nop after the tlbw instruction.
*/
- il_bgezl(p, r, 0, label_tlbw_hazard);
+ uasm_il_bgezl(p, r, 0, label_tlbw_hazard);
tlbw(p);
- l_tlbw_hazard(l, *p);
+ uasm_l_tlbw_hazard(l, *p);
break;
case CPU_RM7000:
- i_nop(p);
- i_nop(p);
- i_nop(p);
- i_nop(p);
+ uasm_i_nop(p);
+ uasm_i_nop(p);
+ uasm_i_nop(p);
+ uasm_i_nop(p);
tlbw(p);
break;
@@ -939,7 +328,7 @@ static __init void build_tlb_write_entry(u32 **p, struct label **l,
case CPU_24K:
case CPU_34K:
case CPU_74K:
- i_ehb(p);
+ uasm_i_ehb(p);
tlbw(p);
break;
@@ -950,15 +339,15 @@ static __init void build_tlb_write_entry(u32 **p, struct label **l,
* cpu cycles and use for data translations should not occur
* for 3 cpu cycles.
*/
- i_ssnop(p);
- i_ssnop(p);
- i_ssnop(p);
- i_ssnop(p);
+ uasm_i_ssnop(p);
+ uasm_i_ssnop(p);
+ uasm_i_ssnop(p);
+ uasm_i_ssnop(p);
tlbw(p);
- i_ssnop(p);
- i_ssnop(p);
- i_ssnop(p);
- i_ssnop(p);
+ uasm_i_ssnop(p);
+ uasm_i_ssnop(p);
+ uasm_i_ssnop(p);
+ uasm_i_ssnop(p);
break;
case CPU_VR4111:
@@ -966,18 +355,18 @@ static __init void build_tlb_write_entry(u32 **p, struct label **l,
case CPU_VR4122:
case CPU_VR4181:
case CPU_VR4181A:
- i_nop(p);
- i_nop(p);
+ uasm_i_nop(p);
+ uasm_i_nop(p);
tlbw(p);
- i_nop(p);
- i_nop(p);
+ uasm_i_nop(p);
+ uasm_i_nop(p);
break;
case CPU_VR4131:
case CPU_VR4133:
case CPU_R5432:
- i_nop(p);
- i_nop(p);
+ uasm_i_nop(p);
+ uasm_i_nop(p);
tlbw(p);
break;
@@ -994,7 +383,7 @@ static __init void build_tlb_write_entry(u32 **p, struct label **l,
* TMP will be clobbered, PTR will hold the pmd entry.
*/
static __init void
-build_get_pmde64(u32 **p, struct label **l, struct reloc **r,
+build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
unsigned int tmp, unsigned int ptr)
{
long pgdc = (long)pgd_current;
@@ -1002,52 +391,52 @@ build_get_pmde64(u32 **p, struct label **l, struct reloc **r,
/*
* The vmalloc handling is not in the hotpath.
*/
- i_dmfc0(p, tmp, C0_BADVADDR);
+ uasm_i_dmfc0(p, tmp, C0_BADVADDR);
#ifdef MODULE_START
- il_bltz(p, r, tmp, label_module_alloc);
+ uasm_il_bltz(p, r, tmp, label_module_alloc);
#else
- il_bltz(p, r, tmp, label_vmalloc);
+ uasm_il_bltz(p, r, tmp, label_vmalloc);
#endif
- /* No i_nop needed here, since the next insn doesn't touch TMP. */
+ /* No uasm_i_nop needed here, since the next insn doesn't touch TMP. */
#ifdef CONFIG_SMP
# ifdef CONFIG_MIPS_MT_SMTC
/*
* SMTC uses TCBind value as "CPU" index
*/
- i_mfc0(p, ptr, C0_TCBIND);
- i_dsrl(p, ptr, ptr, 19);
+ uasm_i_mfc0(p, ptr, C0_TCBIND);
+ uasm_i_dsrl(p, ptr, ptr, 19);
# else
/*
* 64 bit SMP running in XKPHYS has smp_processor_id() << 3
* stored in CONTEXT.
*/
- i_dmfc0(p, ptr, C0_CONTEXT);
- i_dsrl(p, ptr, ptr, 23);
+ uasm_i_dmfc0(p, ptr, C0_CONTEXT);
+ uasm_i_dsrl(p, ptr, ptr, 23);
#endif
- i_LA_mostly(p, tmp, pgdc);
- i_daddu(p, ptr, ptr, tmp);
- i_dmfc0(p, tmp, C0_BADVADDR);
- i_ld(p, ptr, rel_lo(pgdc), ptr);
+ UASM_i_LA_mostly(p, tmp, pgdc);
+ uasm_i_daddu(p, ptr, ptr, tmp);
+ uasm_i_dmfc0(p, tmp, C0_BADVADDR);
+ uasm_i_ld(p, ptr, uasm_rel_lo(pgdc), ptr);
#else
- i_LA_mostly(p, ptr, pgdc);
- i_ld(p, ptr, rel_lo(pgdc), ptr);
+ UASM_i_LA_mostly(p, ptr, pgdc);
+ uasm_i_ld(p, ptr, uasm_rel_lo(pgdc), ptr);
#endif
- l_vmalloc_done(l, *p);
+ uasm_l_vmalloc_done(l, *p);
if (PGDIR_SHIFT - 3 < 32) /* get pgd offset in bytes */
- i_dsrl(p, tmp, tmp, PGDIR_SHIFT-3);
+ uasm_i_dsrl(p, tmp, tmp, PGDIR_SHIFT-3);
else
- i_dsrl32(p, tmp, tmp, PGDIR_SHIFT - 3 - 32);
-
- i_andi(p, tmp, tmp, (PTRS_PER_PGD - 1)<<3);
- i_daddu(p, ptr, ptr, tmp); /* add in pgd offset */
- i_dmfc0(p, tmp, C0_BADVADDR); /* get faulting address */
- i_ld(p, ptr, 0, ptr); /* get pmd pointer */
- i_dsrl(p, tmp, tmp, PMD_SHIFT-3); /* get pmd offset in bytes */
- i_andi(p, tmp, tmp, (PTRS_PER_PMD - 1)<<3);
- i_daddu(p, ptr, ptr, tmp); /* add in pmd offset */
+ uasm_i_dsrl32(p, tmp, tmp, PGDIR_SHIFT - 3 - 32);
+
+ uasm_i_andi(p, tmp, tmp, (PTRS_PER_PGD - 1)<<3);
+ uasm_i_daddu(p, ptr, ptr, tmp); /* add in pgd offset */
+ uasm_i_dmfc0(p, tmp, C0_BADVADDR); /* get faulting address */
+ uasm_i_ld(p, ptr, 0, ptr); /* get pmd pointer */
+ uasm_i_dsrl(p, tmp, tmp, PMD_SHIFT-3); /* get pmd offset in bytes */
+ uasm_i_andi(p, tmp, tmp, (PTRS_PER_PMD - 1)<<3);
+ uasm_i_daddu(p, ptr, ptr, tmp); /* add in pmd offset */
}
/*
@@ -1055,7 +444,7 @@ build_get_pmde64(u32 **p, struct label **l, struct reloc **r,
* PTR will hold the pgd for vmalloc.
*/
static __init void
-build_get_pgd_vmalloc64(u32 **p, struct label **l, struct reloc **r,
+build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
unsigned int bvaddr, unsigned int ptr)
{
long swpd = (long)swapper_pg_dir;
@@ -1063,52 +452,54 @@ build_get_pgd_vmalloc64(u32 **p, struct label **l, struct reloc **r,
#ifdef MODULE_START
long modd = (long)module_pg_dir;
- l_module_alloc(l, *p);
+ uasm_l_module_alloc(l, *p);
/*
* Assumption:
* VMALLOC_START >= 0xc000000000000000UL
* MODULE_START >= 0xe000000000000000UL
*/
- i_SLL(p, ptr, bvaddr, 2);
- il_bgez(p, r, ptr, label_vmalloc);
+ UASM_i_SLL(p, ptr, bvaddr, 2);
+ uasm_il_bgez(p, r, ptr, label_vmalloc);
- if (in_compat_space_p(MODULE_START) && !rel_lo(MODULE_START)) {
- i_lui(p, ptr, rel_hi(MODULE_START)); /* delay slot */
+ if (uasm_in_compat_space_p(MODULE_START) &&
+ !uasm_rel_lo(MODULE_START)) {
+ uasm_i_lui(p, ptr, uasm_rel_hi(MODULE_START)); /* delay slot */
} else {
/* unlikely configuration */
- i_nop(p); /* delay slot */
- i_LA(p, ptr, MODULE_START);
+ uasm_i_nop(p); /* delay slot */
+ UASM_i_LA(p, ptr, MODULE_START);
}
- i_dsubu(p, bvaddr, bvaddr, ptr);
+ uasm_i_dsubu(p, bvaddr, bvaddr, ptr);
- if (in_compat_space_p(modd) && !rel_lo(modd)) {
- il_b(p, r, label_vmalloc_done);
- i_lui(p, ptr, rel_hi(modd));
+ if (uasm_in_compat_space_p(modd) && !uasm_rel_lo(modd)) {
+ uasm_il_b(p, r, label_vmalloc_done);
+ uasm_i_lui(p, ptr, uasm_rel_hi(modd));
} else {
- i_LA_mostly(p, ptr, modd);
- il_b(p, r, label_vmalloc_done);
- i_daddiu(p, ptr, ptr, rel_lo(modd));
+ UASM_i_LA_mostly(p, ptr, modd);
+ uasm_il_b(p, r, label_vmalloc_done);
+ uasm_i_daddiu(p, ptr, ptr, uasm_rel_lo(modd));
}
- l_vmalloc(l, *p);
- if (in_compat_space_p(MODULE_START) && !rel_lo(MODULE_START) &&
+ uasm_l_vmalloc(l, *p);
+ if (uasm_in_compat_space_p(MODULE_START) &&
+ !uasm_rel_lo(MODULE_START) &&
MODULE_START << 32 == VMALLOC_START)
- i_dsll32(p, ptr, ptr, 0); /* typical case */
+ uasm_i_dsll32(p, ptr, ptr, 0); /* typical case */
else
- i_LA(p, ptr, VMALLOC_START);
+ UASM_i_LA(p, ptr, VMALLOC_START);
#else
- l_vmalloc(l, *p);
- i_LA(p, ptr, VMALLOC_START);
+ uasm_l_vmalloc(l, *p);
+ UASM_i_LA(p, ptr, VMALLOC_START);
#endif
- i_dsubu(p, bvaddr, bvaddr, ptr);
+ uasm_i_dsubu(p, bvaddr, bvaddr, ptr);
- if (in_compat_space_p(swpd) && !rel_lo(swpd)) {
- il_b(p, r, label_vmalloc_done);
- i_lui(p, ptr, rel_hi(swpd));
+ if (uasm_in_compat_space_p(swpd) && !uasm_rel_lo(swpd)) {
+ uasm_il_b(p, r, label_vmalloc_done);
+ uasm_i_lui(p, ptr, uasm_rel_hi(swpd));
} else {
- i_LA_mostly(p, ptr, swpd);
- il_b(p, r, label_vmalloc_done);
- i_daddiu(p, ptr, ptr, rel_lo(swpd));
+ UASM_i_LA_mostly(p, ptr, swpd);
+ uasm_il_b(p, r, label_vmalloc_done);
+ uasm_i_daddiu(p, ptr, ptr, uasm_rel_lo(swpd));
}
}
@@ -1129,26 +520,26 @@ build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr)
/*
* SMTC uses TCBind value as "CPU" index
*/
- i_mfc0(p, ptr, C0_TCBIND);
- i_LA_mostly(p, tmp, pgdc);
- i_srl(p, ptr, ptr, 19);
+ uasm_i_mfc0(p, ptr, C0_TCBIND);
+ UASM_i_LA_mostly(p, tmp, pgdc);
+ uasm_i_srl(p, ptr, ptr, 19);
#else
/*
* smp_processor_id() << 3 is stored in CONTEXT.
*/
- i_mfc0(p, ptr, C0_CONTEXT);
- i_LA_mostly(p, tmp, pgdc);
- i_srl(p, ptr, ptr, 23);
+ uasm_i_mfc0(p, ptr, C0_CONTEXT);
+ UASM_i_LA_mostly(p, tmp, pgdc);
+ uasm_i_srl(p, ptr, ptr, 23);
#endif
- i_addu(p, ptr, tmp, ptr);
+ uasm_i_addu(p, ptr, tmp, ptr);
#else
- i_LA_mostly(p, ptr, pgdc);
+ UASM_i_LA_mostly(p, ptr, pgdc);
#endif
- i_mfc0(p, tmp, C0_BADVADDR); /* get faulting address */
- i_lw(p, ptr, rel_lo(pgdc), ptr);
- i_srl(p, tmp, tmp, PGDIR_SHIFT); /* get pgd only bits */
- i_sll(p, tmp, tmp, PGD_T_LOG2);
- i_addu(p, ptr, ptr, tmp); /* add in pgd offset */
+ uasm_i_mfc0(p, tmp, C0_BADVADDR); /* get faulting address */
+ uasm_i_lw(p, ptr, uasm_rel_lo(pgdc), ptr);
+ uasm_i_srl(p, tmp, tmp, PGDIR_SHIFT); /* get pgd only bits */
+ uasm_i_sll(p, tmp, tmp, PGD_T_LOG2);
+ uasm_i_addu(p, ptr, ptr, tmp); /* add in pgd offset */
}
#endif /* !CONFIG_64BIT */
@@ -1175,8 +566,8 @@ static __init void build_adjust_context(u32 **p, unsigned int ctx)
}
if (shift)
- i_SRL(p, ctx, ctx, shift);
- i_andi(p, ctx, ctx, mask);
+ UASM_i_SRL(p, ctx, ctx, shift);
+ uasm_i_andi(p, ctx, ctx, mask);
}
static __init void build_get_ptep(u32 **p, unsigned int tmp, unsigned int ptr)
@@ -1190,18 +581,18 @@ static __init void build_get_ptep(u32 **p, unsigned int tmp, unsigned int ptr)
*/
switch (current_cpu_type()) {
case CPU_NEVADA:
- i_LW(p, ptr, 0, ptr);
+ UASM_i_LW(p, ptr, 0, ptr);
GET_CONTEXT(p, tmp); /* get context reg */
break;
default:
GET_CONTEXT(p, tmp); /* get context reg */
- i_LW(p, ptr, 0, ptr);
+ UASM_i_LW(p, ptr, 0, ptr);
break;
}
build_adjust_context(p, tmp);
- i_ADDU(p, ptr, ptr, tmp); /* add in offset */
+ UASM_i_ADDU(p, ptr, ptr, tmp); /* add in offset */
}
static __init void build_update_entries(u32 **p, unsigned int tmp,
@@ -1213,45 +604,45 @@ static __init void build_update_entries(u32 **p, unsigned int tmp,
*/
#ifdef CONFIG_64BIT_PHYS_ADDR
if (cpu_has_64bits) {
- i_ld(p, tmp, 0, ptep); /* get even pte */
- i_ld(p, ptep, sizeof(pte_t), ptep); /* get odd pte */
- i_dsrl(p, tmp, tmp, 6); /* convert to entrylo0 */
- i_mtc0(p, tmp, C0_ENTRYLO0); /* load it */
- i_dsrl(p, ptep, ptep, 6); /* convert to entrylo1 */
- i_mtc0(p, ptep, C0_ENTRYLO1); /* load it */
+ uasm_i_ld(p, tmp, 0, ptep); /* get even pte */
+ uasm_i_ld(p, ptep, sizeof(pte_t), ptep); /* get odd pte */
+ uasm_i_dsrl(p, tmp, tmp, 6); /* convert to entrylo0 */
+ uasm_i_mtc0(p, tmp, C0_ENTRYLO0); /* load it */
+ uasm_i_dsrl(p, ptep, ptep, 6); /* convert to entrylo1 */
+ uasm_i_mtc0(p, ptep, C0_ENTRYLO1); /* load it */
} else {
int pte_off_even = sizeof(pte_t) / 2;
int pte_off_odd = pte_off_even + sizeof(pte_t);
/* The pte entries are pre-shifted */
- i_lw(p, tmp, pte_off_even, ptep); /* get even pte */
- i_mtc0(p, tmp, C0_ENTRYLO0); /* load it */
- i_lw(p, ptep, pte_off_odd, ptep); /* get odd pte */
- i_mtc0(p, ptep, C0_ENTRYLO1); /* load it */
+ uasm_i_lw(p, tmp, pte_off_even, ptep); /* get even pte */
+ uasm_i_mtc0(p, tmp, C0_ENTRYLO0); /* load it */
+ uasm_i_lw(p, ptep, pte_off_odd, ptep); /* get odd pte */
+ uasm_i_mtc0(p, ptep, C0_ENTRYLO1); /* load it */
}
#else
- i_LW(p, tmp, 0, ptep); /* get even pte */
- i_LW(p, ptep, sizeof(pte_t), ptep); /* get odd pte */
+ UASM_i_LW(p, tmp, 0, ptep); /* get even pte */
+ UASM_i_LW(p, ptep, sizeof(pte_t), ptep); /* get odd pte */
if (r45k_bvahwbug())
build_tlb_probe_entry(p);
- i_SRL(p, tmp, tmp, 6); /* convert to entrylo0 */
+ UASM_i_SRL(p, tmp, tmp, 6); /* convert to entrylo0 */
if (r4k_250MHZhwbug())
- i_mtc0(p, 0, C0_ENTRYLO0);
- i_mtc0(p, tmp, C0_ENTRYLO0); /* load it */
- i_SRL(p, ptep, ptep, 6); /* convert to entrylo1 */
+ uasm_i_mtc0(p, 0, C0_ENTRYLO0);
+ uasm_i_mtc0(p, tmp, C0_ENTRYLO0); /* load it */
+ UASM_i_SRL(p, ptep, ptep, 6); /* convert to entrylo1 */
if (r45k_bvahwbug())
- i_mfc0(p, tmp, C0_INDEX);
+ uasm_i_mfc0(p, tmp, C0_INDEX);
if (r4k_250MHZhwbug())
- i_mtc0(p, 0, C0_ENTRYLO1);
- i_mtc0(p, ptep, C0_ENTRYLO1); /* load it */
+ uasm_i_mtc0(p, 0, C0_ENTRYLO1);
+ uasm_i_mtc0(p, ptep, C0_ENTRYLO1); /* load it */
#endif
}
static void __init build_r4000_tlb_refill_handler(void)
{
u32 *p = tlb_handler;
- struct label *l = labels;
- struct reloc *r = relocs;
+ struct uasm_label *l = labels;
+ struct uasm_reloc *r = relocs;
u32 *f;
unsigned int final_len;
int i;
@@ -1265,12 +656,12 @@ static void __init build_r4000_tlb_refill_handler(void)
* create the plain linear handler
*/
if (bcm1250_m3_war()) {
- i_MFC0(&p, K0, C0_BADVADDR);
- i_MFC0(&p, K1, C0_ENTRYHI);
- i_xor(&p, K0, K0, K1);
- i_SRL(&p, K0, K0, PAGE_SHIFT + 1);
- il_bnez(&p, &r, K0, label_leave);
- /* No need for i_nop */
+ UASM_i_MFC0(&p, K0, C0_BADVADDR);
+ UASM_i_MFC0(&p, K1, C0_ENTRYHI);
+ uasm_i_xor(&p, K0, K0, K1);
+ UASM_i_SRL(&p, K0, K0, PAGE_SHIFT + 1);
+ uasm_il_bnez(&p, &r, K0, label_leave);
+ /* No need for uasm_i_nop */
}
#ifdef CONFIG_64BIT
@@ -1282,8 +673,8 @@ static void __init build_r4000_tlb_refill_handler(void)
build_get_ptep(&p, K0, K1);
build_update_entries(&p, K0, K1);
build_tlb_write_entry(&p, &l, &r, tlb_random);
- l_leave(&l, p);
- i_eret(&p); /* return from trap */
+ uasm_l_leave(&l, p);
+ uasm_i_eret(&p); /* return from trap */
#ifdef CONFIG_64BIT
build_get_pgd_vmalloc64(&p, &l, &r, K0, K1);
@@ -1303,7 +694,7 @@ static void __init build_r4000_tlb_refill_handler(void)
#else
if (((p - tlb_handler) > 63)
|| (((p - tlb_handler) > 61)
- && insn_has_bdelay(relocs, tlb_handler + 29)))
+ && uasm_insn_has_bdelay(relocs, tlb_handler + 29)))
panic("TLB refill handler space exceeded");
#endif
@@ -1313,13 +704,13 @@ static void __init build_r4000_tlb_refill_handler(void)
#if defined(CONFIG_32BIT) || defined(CONFIG_CPU_LOONGSON2)
f = final_handler;
/* Simplest case, just copy the handler. */
- copy_handler(relocs, labels, tlb_handler, p, f);
+ uasm_copy_handler(relocs, labels, tlb_handler, p, f);
final_len = p - tlb_handler;
#else /* CONFIG_64BIT */
f = final_handler + 32;
if ((p - tlb_handler) <= 32) {
/* Just copy the handler. */
- copy_handler(relocs, labels, tlb_handler, p, f);
+ uasm_copy_handler(relocs, labels, tlb_handler, p, f);
final_len = p - tlb_handler;
} else {
u32 *split = tlb_handler + 30;
@@ -1327,34 +718,34 @@ static void __init build_r4000_tlb_refill_handler(void)
/*
* Find the split point.
*/
- if (insn_has_bdelay(relocs, split - 1))
+ if (uasm_insn_has_bdelay(relocs, split - 1))
split--;
/* Copy first part of the handler. */
- copy_handler(relocs, labels, tlb_handler, split, f);
+ uasm_copy_handler(relocs, labels, tlb_handler, split, f);
f += split - tlb_handler;
/* Insert branch. */
- l_split(&l, final_handler);
- il_b(&f, &r, label_split);
- if (insn_has_bdelay(relocs, split))
- i_nop(&f);
+ uasm_l_split(&l, final_handler);
+ uasm_il_b(&f, &r, label_split);
+ if (uasm_insn_has_bdelay(relocs, split))
+ uasm_i_nop(&f);
else {
- copy_handler(relocs, labels, split, split + 1, f);
- move_labels(labels, f, f + 1, -1);
+ uasm_copy_handler(relocs, labels, split, split + 1, f);
+ uasm_move_labels(labels, f, f + 1, -1);
f++;
split++;
}
/* Copy the rest of the handler. */
- copy_handler(relocs, labels, split, p, final_handler);
+ uasm_copy_handler(relocs, labels, split, p, final_handler);
final_len = (f - (final_handler + 32)) + (p - split);
}
#endif /* CONFIG_64BIT */
- resolve_relocs(relocs, labels);
- pr_info("Synthesized TLB refill handler (%u instructions).\n",
- final_len);
+ uasm_resolve_relocs(relocs, labels);
+ pr_debug("Wrote TLB refill handler (%u instructions).\n",
+ final_len);
f = final_handler;
#if defined(CONFIG_64BIT) && !defined(CONFIG_CPU_LOONGSON2)
@@ -1395,75 +786,75 @@ u32 __tlb_handler_align handle_tlbs[FASTPATH_SIZE];
u32 __tlb_handler_align handle_tlbm[FASTPATH_SIZE];
static void __init
-iPTE_LW(u32 **p, struct label **l, unsigned int pte, unsigned int ptr)
+iPTE_LW(u32 **p, struct uasm_label **l, unsigned int pte, unsigned int ptr)
{
#ifdef CONFIG_SMP
# ifdef CONFIG_64BIT_PHYS_ADDR
if (cpu_has_64bits)
- i_lld(p, pte, 0, ptr);
+ uasm_i_lld(p, pte, 0, ptr);
else
# endif
- i_LL(p, pte, 0, ptr);
+ UASM_i_LL(p, pte, 0, ptr);
#else
# ifdef CONFIG_64BIT_PHYS_ADDR
if (cpu_has_64bits)
- i_ld(p, pte, 0, ptr);
+ uasm_i_ld(p, pte, 0, ptr);
else
# endif
- i_LW(p, pte, 0, ptr);
+ UASM_i_LW(p, pte, 0, ptr);
#endif
}
static void __init
-iPTE_SW(u32 **p, struct reloc **r, unsigned int pte, unsigned int ptr,
+iPTE_SW(u32 **p, struct uasm_reloc **r, unsigned int pte, unsigned int ptr,
unsigned int mode)
{
#ifdef CONFIG_64BIT_PHYS_ADDR
unsigned int hwmode = mode & (_PAGE_VALID | _PAGE_DIRTY);
#endif
- i_ori(p, pte, pte, mode);
+ uasm_i_ori(p, pte, pte, mode);
#ifdef CONFIG_SMP
# ifdef CONFIG_64BIT_PHYS_ADDR
if (cpu_has_64bits)
- i_scd(p, pte, 0, ptr);
+ uasm_i_scd(p, pte, 0, ptr);
else
# endif
- i_SC(p, pte, 0, ptr);
+ UASM_i_SC(p, pte, 0, ptr);
if (r10000_llsc_war())
- il_beqzl(p, r, pte, label_smp_pgtable_change);
+ uasm_il_beqzl(p, r, pte, label_smp_pgtable_change);
else
- il_beqz(p, r, pte, label_smp_pgtable_change);
+ uasm_il_beqz(p, r, pte, label_smp_pgtable_change);
# ifdef CONFIG_64BIT_PHYS_ADDR
if (!cpu_has_64bits) {
- /* no i_nop needed */
- i_ll(p, pte, sizeof(pte_t) / 2, ptr);
- i_ori(p, pte, pte, hwmode);
- i_sc(p, pte, sizeof(pte_t) / 2, ptr);
- il_beqz(p, r, pte, label_smp_pgtable_change);
- /* no i_nop needed */
- i_lw(p, pte, 0, ptr);
+ /* no uasm_i_nop needed */
+ uasm_i_ll(p, pte, sizeof(pte_t) / 2, ptr);
+ uasm_i_ori(p, pte, pte, hwmode);
+ uasm_i_sc(p, pte, sizeof(pte_t) / 2, ptr);
+ uasm_il_beqz(p, r, pte, label_smp_pgtable_change);
+ /* no uasm_i_nop needed */
+ uasm_i_lw(p, pte, 0, ptr);
} else
- i_nop(p);
+ uasm_i_nop(p);
# else
- i_nop(p);
+ uasm_i_nop(p);
# endif
#else
# ifdef CONFIG_64BIT_PHYS_ADDR
if (cpu_has_64bits)
- i_sd(p, pte, 0, ptr);
+ uasm_i_sd(p, pte, 0, ptr);
else
# endif
- i_SW(p, pte, 0, ptr);
+ UASM_i_SW(p, pte, 0, ptr);
# ifdef CONFIG_64BIT_PHYS_ADDR
if (!cpu_has_64bits) {
- i_lw(p, pte, sizeof(pte_t) / 2, ptr);
- i_ori(p, pte, pte, hwmode);
- i_sw(p, pte, sizeof(pte_t) / 2, ptr);
- i_lw(p, pte, 0, ptr);
+ uasm_i_lw(p, pte, sizeof(pte_t) / 2, ptr);
+ uasm_i_ori(p, pte, pte, hwmode);
+ uasm_i_sw(p, pte, sizeof(pte_t) / 2, ptr);
+ uasm_i_lw(p, pte, 0, ptr);
}
# endif
#endif
@@ -1475,18 +866,18 @@ iPTE_SW(u32 **p, struct reloc **r, unsigned int pte, unsigned int ptr,
* with it's original value.
*/
static void __init
-build_pte_present(u32 **p, struct label **l, struct reloc **r,
+build_pte_present(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
unsigned int pte, unsigned int ptr, enum label_id lid)
{
- i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_READ);
- i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_READ);
- il_bnez(p, r, pte, lid);
+ uasm_i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_READ);
+ uasm_i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_READ);
+ uasm_il_bnez(p, r, pte, lid);
iPTE_LW(p, l, pte, ptr);
}
/* Make PTE valid, store result in PTR. */
static void __init
-build_make_valid(u32 **p, struct reloc **r, unsigned int pte,
+build_make_valid(u32 **p, struct uasm_reloc **r, unsigned int pte,
unsigned int ptr)
{
unsigned int mode = _PAGE_VALID | _PAGE_ACCESSED;
@@ -1499,12 +890,12 @@ build_make_valid(u32 **p, struct reloc **r, unsigned int pte,
* restore PTE with value from PTR when done.
*/
static void __init
-build_pte_writable(u32 **p, struct label **l, struct reloc **r,
+build_pte_writable(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
unsigned int pte, unsigned int ptr, enum label_id lid)
{
- i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE);
- i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE);
- il_bnez(p, r, pte, lid);
+ uasm_i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE);
+ uasm_i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE);
+ uasm_il_bnez(p, r, pte, lid);
iPTE_LW(p, l, pte, ptr);
}
@@ -1512,7 +903,7 @@ build_pte_writable(u32 **p, struct label **l, struct reloc **r,
* at PTR.
*/
static void __init
-build_make_write(u32 **p, struct reloc **r, unsigned int pte,
+build_make_write(u32 **p, struct uasm_reloc **r, unsigned int pte,
unsigned int ptr)
{
unsigned int mode = (_PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_VALID
@@ -1526,11 +917,11 @@ build_make_write(u32 **p, struct reloc **r, unsigned int pte,
* restore PTE with value from PTR when done.
*/
static void __init
-build_pte_modifiable(u32 **p, struct label **l, struct reloc **r,
+build_pte_modifiable(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
unsigned int pte, unsigned int ptr, enum label_id lid)
{
- i_andi(p, pte, pte, _PAGE_WRITE);
- il_beqz(p, r, pte, lid);
+ uasm_i_andi(p, pte, pte, _PAGE_WRITE);
+ uasm_il_beqz(p, r, pte, lid);
iPTE_LW(p, l, pte, ptr);
}
@@ -1545,11 +936,11 @@ build_pte_modifiable(u32 **p, struct label **l, struct reloc **r,
static void __init
build_r3000_pte_reload_tlbwi(u32 **p, unsigned int pte, unsigned int tmp)
{
- i_mtc0(p, pte, C0_ENTRYLO0); /* cp0 delay */
- i_mfc0(p, tmp, C0_EPC); /* cp0 delay */
- i_tlbwi(p);
- i_jr(p, tmp);
- i_rfe(p); /* branch delay */
+ uasm_i_mtc0(p, pte, C0_ENTRYLO0); /* cp0 delay */
+ uasm_i_mfc0(p, tmp, C0_EPC); /* cp0 delay */
+ uasm_i_tlbwi(p);
+ uasm_i_jr(p, tmp);
+ uasm_i_rfe(p); /* branch delay */
}
/*
@@ -1559,20 +950,21 @@ build_r3000_pte_reload_tlbwi(u32 **p, unsigned int pte, unsigned int tmp)
* kseg2 access, i.e. without refill. Then it returns.
*/
static void __init
-build_r3000_tlb_reload_write(u32 **p, struct label **l, struct reloc **r,
- unsigned int pte, unsigned int tmp)
-{
- i_mfc0(p, tmp, C0_INDEX);
- i_mtc0(p, pte, C0_ENTRYLO0); /* cp0 delay */
- il_bltz(p, r, tmp, label_r3000_write_probe_fail); /* cp0 delay */
- i_mfc0(p, tmp, C0_EPC); /* branch delay */
- i_tlbwi(p); /* cp0 delay */
- i_jr(p, tmp);
- i_rfe(p); /* branch delay */
- l_r3000_write_probe_fail(l, *p);
- i_tlbwr(p); /* cp0 delay */
- i_jr(p, tmp);
- i_rfe(p); /* branch delay */
+build_r3000_tlb_reload_write(u32 **p, struct uasm_label **l,
+ struct uasm_reloc **r, unsigned int pte,
+ unsigned int tmp)
+{
+ uasm_i_mfc0(p, tmp, C0_INDEX);
+ uasm_i_mtc0(p, pte, C0_ENTRYLO0); /* cp0 delay */
+ uasm_il_bltz(p, r, tmp, label_r3000_write_probe_fail); /* cp0 delay */
+ uasm_i_mfc0(p, tmp, C0_EPC); /* branch delay */
+ uasm_i_tlbwi(p); /* cp0 delay */
+ uasm_i_jr(p, tmp);
+ uasm_i_rfe(p); /* branch delay */
+ uasm_l_r3000_write_probe_fail(l, *p);
+ uasm_i_tlbwr(p); /* cp0 delay */
+ uasm_i_jr(p, tmp);
+ uasm_i_rfe(p); /* branch delay */
}
static void __init
@@ -1581,25 +973,25 @@ build_r3000_tlbchange_handler_head(u32 **p, unsigned int pte,
{
long pgdc = (long)pgd_current;
- i_mfc0(p, pte, C0_BADVADDR);
- i_lui(p, ptr, rel_hi(pgdc)); /* cp0 delay */
- i_lw(p, ptr, rel_lo(pgdc), ptr);
- i_srl(p, pte, pte, 22); /* load delay */
- i_sll(p, pte, pte, 2);
- i_addu(p, ptr, ptr, pte);
- i_mfc0(p, pte, C0_CONTEXT);
- i_lw(p, ptr, 0, ptr); /* cp0 delay */
- i_andi(p, pte, pte, 0xffc); /* load delay */
- i_addu(p, ptr, ptr, pte);
- i_lw(p, pte, 0, ptr);
- i_tlbp(p); /* load delay */
+ uasm_i_mfc0(p, pte, C0_BADVADDR);
+ uasm_i_lui(p, ptr, uasm_rel_hi(pgdc)); /* cp0 delay */
+ uasm_i_lw(p, ptr, uasm_rel_lo(pgdc), ptr);
+ uasm_i_srl(p, pte, pte, 22); /* load delay */
+ uasm_i_sll(p, pte, pte, 2);
+ uasm_i_addu(p, ptr, ptr, pte);
+ uasm_i_mfc0(p, pte, C0_CONTEXT);
+ uasm_i_lw(p, ptr, 0, ptr); /* cp0 delay */
+ uasm_i_andi(p, pte, pte, 0xffc); /* load delay */
+ uasm_i_addu(p, ptr, ptr, pte);
+ uasm_i_lw(p, pte, 0, ptr);
+ uasm_i_tlbp(p); /* load delay */
}
static void __init build_r3000_tlb_load_handler(void)
{
u32 *p = handle_tlbl;
- struct label *l = labels;
- struct reloc *r = relocs;
+ struct uasm_label *l = labels;
+ struct uasm_reloc *r = relocs;
int i;
memset(handle_tlbl, 0, sizeof(handle_tlbl));
@@ -1608,20 +1000,20 @@ static void __init build_r3000_tlb_load_handler(void)
build_r3000_tlbchange_handler_head(&p, K0, K1);
build_pte_present(&p, &l, &r, K0, K1, label_nopage_tlbl);
- i_nop(&p); /* load delay */
+ uasm_i_nop(&p); /* load delay */
build_make_valid(&p, &r, K0, K1);
build_r3000_tlb_reload_write(&p, &l, &r, K0, K1);
- l_nopage_tlbl(&l, p);
- i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff);
- i_nop(&p);
+ uasm_l_nopage_tlbl(&l, p);
+ uasm_i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff);
+ uasm_i_nop(&p);
if ((p - handle_tlbl) > FASTPATH_SIZE)
panic("TLB load handler fastpath space exceeded");
- resolve_relocs(relocs, labels);
- pr_info("Synthesized TLB load handler fastpath (%u instructions).\n",
- (unsigned int)(p - handle_tlbl));
+ uasm_resolve_relocs(relocs, labels);
+ pr_debug("Wrote TLB load handler fastpath (%u instructions).\n",
+ (unsigned int)(p - handle_tlbl));
pr_debug("\t.set push\n");
pr_debug("\t.set noreorder\n");
@@ -1633,8 +1025,8 @@ static void __init build_r3000_tlb_load_handler(void)
static void __init build_r3000_tlb_store_handler(void)
{
u32 *p = handle_tlbs;
- struct label *l = labels;
- struct reloc *r = relocs;
+ struct uasm_label *l = labels;
+ struct uasm_reloc *r = relocs;
int i;
memset(handle_tlbs, 0, sizeof(handle_tlbs));
@@ -1643,20 +1035,20 @@ static void __init build_r3000_tlb_store_handler(void)
build_r3000_tlbchange_handler_head(&p, K0, K1);
build_pte_writable(&p, &l, &r, K0, K1, label_nopage_tlbs);
- i_nop(&p); /* load delay */
+ uasm_i_nop(&p); /* load delay */
build_make_write(&p, &r, K0, K1);
build_r3000_tlb_reload_write(&p, &l, &r, K0, K1);
- l_nopage_tlbs(&l, p);
- i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
- i_nop(&p);
+ uasm_l_nopage_tlbs(&l, p);
+ uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
+ uasm_i_nop(&p);
if ((p - handle_tlbs) > FASTPATH_SIZE)
panic("TLB store handler fastpath space exceeded");
- resolve_relocs(relocs, labels);
- pr_info("Synthesized TLB store handler fastpath (%u instructions).\n",
- (unsigned int)(p - handle_tlbs));
+ uasm_resolve_relocs(relocs, labels);
+ pr_debug("Wrote TLB store handler fastpath (%u instructions).\n",
+ (unsigned int)(p - handle_tlbs));
pr_debug("\t.set push\n");
pr_debug("\t.set noreorder\n");
@@ -1668,8 +1060,8 @@ static void __init build_r3000_tlb_store_handler(void)
static void __init build_r3000_tlb_modify_handler(void)
{
u32 *p = handle_tlbm;
- struct label *l = labels;
- struct reloc *r = relocs;
+ struct uasm_label *l = labels;
+ struct uasm_reloc *r = relocs;
int i;
memset(handle_tlbm, 0, sizeof(handle_tlbm));
@@ -1678,20 +1070,20 @@ static void __init build_r3000_tlb_modify_handler(void)
build_r3000_tlbchange_handler_head(&p, K0, K1);
build_pte_modifiable(&p, &l, &r, K0, K1, label_nopage_tlbm);
- i_nop(&p); /* load delay */
+ uasm_i_nop(&p); /* load delay */
build_make_write(&p, &r, K0, K1);
build_r3000_pte_reload_tlbwi(&p, K0, K1);
- l_nopage_tlbm(&l, p);
- i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
- i_nop(&p);
+ uasm_l_nopage_tlbm(&l, p);
+ uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
+ uasm_i_nop(&p);
if ((p - handle_tlbm) > FASTPATH_SIZE)
panic("TLB modify handler fastpath space exceeded");
- resolve_relocs(relocs, labels);
- pr_info("Synthesized TLB modify handler fastpath (%u instructions).\n",
- (unsigned int)(p - handle_tlbm));
+ uasm_resolve_relocs(relocs, labels);
+ pr_debug("Wrote TLB modify handler fastpath (%u instructions).\n",
+ (unsigned int)(p - handle_tlbm));
pr_debug("\t.set push\n");
pr_debug("\t.set noreorder\n");
@@ -1704,8 +1096,8 @@ static void __init build_r3000_tlb_modify_handler(void)
* R4000 style TLB load/store/modify handlers.
*/
static void __init
-build_r4000_tlbchange_handler_head(u32 **p, struct label **l,
- struct reloc **r, unsigned int pte,
+build_r4000_tlbchange_handler_head(u32 **p, struct uasm_label **l,
+ struct uasm_reloc **r, unsigned int pte,
unsigned int ptr)
{
#ifdef CONFIG_64BIT
@@ -1714,14 +1106,14 @@ build_r4000_tlbchange_handler_head(u32 **p, struct label **l,
build_get_pgde32(p, pte, ptr); /* get pgd in ptr */
#endif
- i_MFC0(p, pte, C0_BADVADDR);
- i_LW(p, ptr, 0, ptr);
- i_SRL(p, pte, pte, PAGE_SHIFT + PTE_ORDER - PTE_T_LOG2);
- i_andi(p, pte, pte, (PTRS_PER_PTE - 1) << PTE_T_LOG2);
- i_ADDU(p, ptr, ptr, pte);
+ UASM_i_MFC0(p, pte, C0_BADVADDR);
+ UASM_i_LW(p, ptr, 0, ptr);
+ UASM_i_SRL(p, pte, pte, PAGE_SHIFT + PTE_ORDER - PTE_T_LOG2);
+ uasm_i_andi(p, pte, pte, (PTRS_PER_PTE - 1) << PTE_T_LOG2);
+ UASM_i_ADDU(p, ptr, ptr, pte);
#ifdef CONFIG_SMP
- l_smp_pgtable_change(l, *p);
+ uasm_l_smp_pgtable_change(l, *p);
# endif
iPTE_LW(p, l, pte, ptr); /* get even pte */
if (!m4kc_tlbp_war())
@@ -1729,16 +1121,16 @@ build_r4000_tlbchange_handler_head(u32 **p, struct label **l,
}
static void __init
-build_r4000_tlbchange_handler_tail(u32 **p, struct label **l,
- struct reloc **r, unsigned int tmp,
+build_r4000_tlbchange_handler_tail(u32 **p, struct uasm_label **l,
+ struct uasm_reloc **r, unsigned int tmp,
unsigned int ptr)
{
- i_ori(p, ptr, ptr, sizeof(pte_t));
- i_xori(p, ptr, ptr, sizeof(pte_t));
+ uasm_i_ori(p, ptr, ptr, sizeof(pte_t));
+ uasm_i_xori(p, ptr, ptr, sizeof(pte_t));
build_update_entries(p, tmp, ptr);
build_tlb_write_entry(p, l, r, tlb_indexed);
- l_leave(l, *p);
- i_eret(p); /* return from trap */
+ uasm_l_leave(l, *p);
+ uasm_i_eret(p); /* return from trap */
#ifdef CONFIG_64BIT
build_get_pgd_vmalloc64(p, l, r, tmp, ptr);
@@ -1748,8 +1140,8 @@ build_r4000_tlbchange_handler_tail(u32 **p, struct label **l,
static void __init build_r4000_tlb_load_handler(void)
{
u32 *p = handle_tlbl;
- struct label *l = labels;
- struct reloc *r = relocs;
+ struct uasm_label *l = labels;
+ struct uasm_reloc *r = relocs;
int i;
memset(handle_tlbl, 0, sizeof(handle_tlbl));
@@ -1757,12 +1149,12 @@ static void __init build_r4000_tlb_load_handler(void)
memset(relocs, 0, sizeof(relocs));
if (bcm1250_m3_war()) {
- i_MFC0(&p, K0, C0_BADVADDR);
- i_MFC0(&p, K1, C0_ENTRYHI);
- i_xor(&p, K0, K0, K1);
- i_SRL(&p, K0, K0, PAGE_SHIFT + 1);
- il_bnez(&p, &r, K0, label_leave);
- /* No need for i_nop */
+ UASM_i_MFC0(&p, K0, C0_BADVADDR);
+ UASM_i_MFC0(&p, K1, C0_ENTRYHI);
+ uasm_i_xor(&p, K0, K0, K1);
+ UASM_i_SRL(&p, K0, K0, PAGE_SHIFT + 1);
+ uasm_il_bnez(&p, &r, K0, label_leave);
+ /* No need for uasm_i_nop */
}
build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1);
@@ -1772,16 +1164,16 @@ static void __init build_r4000_tlb_load_handler(void)
build_make_valid(&p, &r, K0, K1);
build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1);
- l_nopage_tlbl(&l, p);
- i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff);
- i_nop(&p);
+ uasm_l_nopage_tlbl(&l, p);
+ uasm_i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff);
+ uasm_i_nop(&p);
if ((p - handle_tlbl) > FASTPATH_SIZE)
panic("TLB load handler fastpath space exceeded");
- resolve_relocs(relocs, labels);
- pr_info("Synthesized TLB load handler fastpath (%u instructions).\n",
- (unsigned int)(p - handle_tlbl));
+ uasm_resolve_relocs(relocs, labels);
+ pr_debug("Wrote TLB load handler fastpath (%u instructions).\n",
+ (unsigned int)(p - handle_tlbl));
pr_debug("\t.set push\n");
pr_debug("\t.set noreorder\n");
@@ -1793,8 +1185,8 @@ static void __init build_r4000_tlb_load_handler(void)
static void __init build_r4000_tlb_store_handler(void)
{
u32 *p = handle_tlbs;
- struct label *l = labels;
- struct reloc *r = relocs;
+ struct uasm_label *l = labels;
+ struct uasm_reloc *r = relocs;
int i;
memset(handle_tlbs, 0, sizeof(handle_tlbs));
@@ -1808,16 +1200,16 @@ static void __init build_r4000_tlb_store_handler(void)
build_make_write(&p, &r, K0, K1);
build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1);
- l_nopage_tlbs(&l, p);
- i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
- i_nop(&p);
+ uasm_l_nopage_tlbs(&l, p);
+ uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
+ uasm_i_nop(&p);
if ((p - handle_tlbs) > FASTPATH_SIZE)
panic("TLB store handler fastpath space exceeded");
- resolve_relocs(relocs, labels);
- pr_info("Synthesized TLB store handler fastpath (%u instructions).\n",
- (unsigned int)(p - handle_tlbs));
+ uasm_resolve_relocs(relocs, labels);
+ pr_debug("Wrote TLB store handler fastpath (%u instructions).\n",
+ (unsigned int)(p - handle_tlbs));
pr_debug("\t.set push\n");
pr_debug("\t.set noreorder\n");
@@ -1829,8 +1221,8 @@ static void __init build_r4000_tlb_store_handler(void)
static void __init build_r4000_tlb_modify_handler(void)
{
u32 *p = handle_tlbm;
- struct label *l = labels;
- struct reloc *r = relocs;
+ struct uasm_label *l = labels;
+ struct uasm_reloc *r = relocs;
int i;
memset(handle_tlbm, 0, sizeof(handle_tlbm));
@@ -1845,16 +1237,16 @@ static void __init build_r4000_tlb_modify_handler(void)
build_make_write(&p, &r, K0, K1);
build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1);
- l_nopage_tlbm(&l, p);
- i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
- i_nop(&p);
+ uasm_l_nopage_tlbm(&l, p);
+ uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
+ uasm_i_nop(&p);
if ((p - handle_tlbm) > FASTPATH_SIZE)
panic("TLB modify handler fastpath space exceeded");
- resolve_relocs(relocs, labels);
- pr_info("Synthesized TLB modify handler fastpath (%u instructions).\n",
- (unsigned int)(p - handle_tlbm));
+ uasm_resolve_relocs(relocs, labels);
+ pr_debug("Wrote TLB modify handler fastpath (%u instructions).\n",
+ (unsigned int)(p - handle_tlbm));
pr_debug("\t.set push\n");
pr_debug("\t.set noreorder\n");
diff --git a/arch/mips/mm/uasm.c b/arch/mips/mm/uasm.c
new file mode 100644
index 0000000..889176a
--- /dev/null
+++ b/arch/mips/mm/uasm.c
@@ -0,0 +1,566 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * A small micro-assembler. It is intentionally kept simple, does only
+ * support a subset of instructions, and does not try to hide pipeline
+ * effects like branch delay slots.
+ *
+ * Copyright (C) 2004,2005,2006,2008 Thiemo Seufer
+ * Copyright (C) 2005 Maciej W. Rozycki
+ * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org)
+ */
+
+#include <stdarg.h>
+
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+
+#include <asm/inst.h>
+#include <asm/elf.h>
+
+#include "uasm.h"
+
+enum fields {
+ RS = 0x001,
+ RT = 0x002,
+ RD = 0x004,
+ RE = 0x008,
+ SIMM = 0x010,
+ UIMM = 0x020,
+ BIMM = 0x040,
+ JIMM = 0x080,
+ FUNC = 0x100,
+ SET = 0x200
+};
+
+#define OP_MASK 0x3f
+#define OP_SH 26
+#define RS_MASK 0x1f
+#define RS_SH 21
+#define RT_MASK 0x1f
+#define RT_SH 16
+#define RD_MASK 0x1f
+#define RD_SH 11
+#define RE_MASK 0x1f
+#define RE_SH 6
+#define IMM_MASK 0xffff
+#define IMM_SH 0
+#define JIMM_MASK 0x3ffffff
+#define JIMM_SH 0
+#define FUNC_MASK 0x3f
+#define FUNC_SH 0
+#define SET_MASK 0x7
+#define SET_SH 0
+
+enum opcode {
+ insn_invalid,
+ insn_addu, insn_addiu, insn_and, insn_andi, insn_beq,
+ insn_beql, insn_bgez, insn_bgezl, insn_bltz, insn_bltzl,
+ insn_bne, insn_daddu, insn_daddiu, insn_dmfc0, insn_dmtc0,
+ insn_dsll, insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32,
+ insn_dsubu, insn_eret, insn_j, insn_jal, insn_jr, insn_ld,
+ insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0, insn_mtc0,
+ insn_ori, insn_rfe, insn_sc, insn_scd, insn_sd, insn_sll,
+ insn_sra, insn_srl, insn_subu, insn_sw, insn_tlbp, insn_tlbwi,
+ insn_tlbwr, insn_xor, insn_xori
+};
+
+struct insn {
+ enum opcode opcode;
+ u32 match;
+ enum fields fields;
+};
+
+/* This macro sets the non-variable bits of an instruction. */
+#define M(a, b, c, d, e, f) \
+ ((a) << OP_SH \
+ | (b) << RS_SH \
+ | (c) << RT_SH \
+ | (d) << RD_SH \
+ | (e) << RE_SH \
+ | (f) << FUNC_SH)
+
+static __initdata struct insn insn_table[] = {
+ { insn_addiu, M(addiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
+ { insn_addu, M(spec_op, 0, 0, 0, 0, addu_op), RS | RT | RD },
+ { insn_and, M(spec_op, 0, 0, 0, 0, and_op), RS | RT | RD },
+ { insn_andi, M(andi_op, 0, 0, 0, 0, 0), RS | RT | UIMM },
+ { insn_beq, M(beq_op, 0, 0, 0, 0, 0), RS | RT | BIMM },
+ { insn_beql, M(beql_op, 0, 0, 0, 0, 0), RS | RT | BIMM },
+ { insn_bgez, M(bcond_op, 0, bgez_op, 0, 0, 0), RS | BIMM },
+ { insn_bgezl, M(bcond_op, 0, bgezl_op, 0, 0, 0), RS | BIMM },
+ { insn_bltz, M(bcond_op, 0, bltz_op, 0, 0, 0), RS | BIMM },
+ { insn_bltzl, M(bcond_op, 0, bltzl_op, 0, 0, 0), RS | BIMM },
+ { insn_bne, M(bne_op, 0, 0, 0, 0, 0), RS | RT | BIMM },
+ { insn_daddiu, M(daddiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
+ { insn_daddu, M(spec_op, 0, 0, 0, 0, daddu_op), RS | RT | RD },
+ { insn_dmfc0, M(cop0_op, dmfc_op, 0, 0, 0, 0), RT | RD | SET},
+ { insn_dmtc0, M(cop0_op, dmtc_op, 0, 0, 0, 0), RT | RD | SET},
+ { insn_dsll, M(spec_op, 0, 0, 0, 0, dsll_op), RT | RD | RE },
+ { insn_dsll32, M(spec_op, 0, 0, 0, 0, dsll32_op), RT | RD | RE },
+ { insn_dsra, M(spec_op, 0, 0, 0, 0, dsra_op), RT | RD | RE },
+ { insn_dsrl, M(spec_op, 0, 0, 0, 0, dsrl_op), RT | RD | RE },
+ { insn_dsrl32, M(spec_op, 0, 0, 0, 0, dsrl32_op), RT | RD | RE },
+ { insn_dsubu, M(spec_op, 0, 0, 0, 0, dsubu_op), RS | RT | RD },
+ { insn_eret, M(cop0_op, cop_op, 0, 0, 0, eret_op), 0 },
+ { insn_j, M(j_op, 0, 0, 0, 0, 0), JIMM },
+ { insn_jal, M(jal_op, 0, 0, 0, 0, 0), JIMM },
+ { insn_jr, M(spec_op, 0, 0, 0, 0, jr_op), RS },
+ { insn_ld, M(ld_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
+ { insn_ll, M(ll_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
+ { insn_lld, M(lld_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
+ { insn_lui, M(lui_op, 0, 0, 0, 0, 0), RT | SIMM },
+ { insn_lw, M(lw_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
+ { insn_mfc0, M(cop0_op, mfc_op, 0, 0, 0, 0), RT | RD | SET},
+ { insn_mtc0, M(cop0_op, mtc_op, 0, 0, 0, 0), RT | RD | SET},
+ { insn_ori, M(ori_op, 0, 0, 0, 0, 0), RS | RT | UIMM },
+ { insn_rfe, M(cop0_op, cop_op, 0, 0, 0, rfe_op), 0 },
+ { insn_sc, M(sc_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
+ { insn_scd, M(scd_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
+ { insn_sd, M(sd_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
+ { insn_sll, M(spec_op, 0, 0, 0, 0, sll_op), RT | RD | RE },
+ { insn_sra, M(spec_op, 0, 0, 0, 0, sra_op), RT | RD | RE },
+ { insn_srl, M(spec_op, 0, 0, 0, 0, srl_op), RT | RD | RE },
+ { insn_subu, M(spec_op, 0, 0, 0, 0, subu_op), RS | RT | RD },
+ { insn_sw, M(sw_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
+ { insn_tlbp, M(cop0_op, cop_op, 0, 0, 0, tlbp_op), 0 },
+ { insn_tlbwi, M(cop0_op, cop_op, 0, 0, 0, tlbwi_op), 0 },
+ { insn_tlbwr, M(cop0_op, cop_op, 0, 0, 0, tlbwr_op), 0 },
+ { insn_xor, M(spec_op, 0, 0, 0, 0, xor_op), RS | RT | RD },
+ { insn_xori, M(xori_op, 0, 0, 0, 0, 0), RS | RT | UIMM },
+ { insn_invalid, 0, 0 }
+};
+
+#undef M
+
+static inline __init u32 build_rs(u32 arg)
+{
+ if (arg & ~RS_MASK)
+ printk(KERN_WARNING "Micro-assembler field overflow\n");
+
+ return (arg & RS_MASK) << RS_SH;
+}
+
+static inline __init u32 build_rt(u32 arg)
+{
+ if (arg & ~RT_MASK)
+ printk(KERN_WARNING "Micro-assembler field overflow\n");
+
+ return (arg & RT_MASK) << RT_SH;
+}
+
+static inline __init u32 build_rd(u32 arg)
+{
+ if (arg & ~RD_MASK)
+ printk(KERN_WARNING "Micro-assembler field overflow\n");
+
+ return (arg & RD_MASK) << RD_SH;
+}
+
+static inline __init u32 build_re(u32 arg)
+{
+ if (arg & ~RE_MASK)
+ printk(KERN_WARNING "Micro-assembler field overflow\n");
+
+ return (arg & RE_MASK) << RE_SH;
+}
+
+static inline __init u32 build_simm(s32 arg)
+{
+ if (arg > 0x7fff || arg < -0x8000)
+ printk(KERN_WARNING "Micro-assembler field overflow\n");
+
+ return arg & 0xffff;
+}
+
+static inline __init u32 build_uimm(u32 arg)
+{
+ if (arg & ~IMM_MASK)
+ printk(KERN_WARNING "Micro-assembler field overflow\n");
+
+ return arg & IMM_MASK;
+}
+
+static inline __init u32 build_bimm(s32 arg)
+{
+ if (arg > 0x1ffff || arg < -0x20000)
+ printk(KERN_WARNING "Micro-assembler field overflow\n");
+
+ if (arg & 0x3)
+ printk(KERN_WARNING "Invalid micro-assembler branch target\n");
+
+ return ((arg < 0) ? (1 << 15) : 0) | ((arg >> 2) & 0x7fff);
+}
+
+static inline __init u32 build_jimm(u32 arg)
+{
+ if (arg & ~((JIMM_MASK) << 2))
+ printk(KERN_WARNING "Micro-assembler field overflow\n");
+
+ return (arg >> 2) & JIMM_MASK;
+}
+
+static inline __init u32 build_func(u32 arg)
+{
+ if (arg & ~FUNC_MASK)
+ printk(KERN_WARNING "Micro-assembler field overflow\n");
+
+ return arg & FUNC_MASK;
+}
+
+static inline __init u32 build_set(u32 arg)
+{
+ if (arg & ~SET_MASK)
+ printk(KERN_WARNING "Micro-assembler field overflow\n");
+
+ return arg & SET_MASK;
+}
+
+/*
+ * The order of opcode arguments is implicitly left to right,
+ * starting with RS and ending with FUNC or IMM.
+ */
+static void __init build_insn(u32 **buf, enum opcode opc, ...)
+{
+ struct insn *ip = NULL;
+ unsigned int i;
+ va_list ap;
+ u32 op;
+
+ for (i = 0; insn_table[i].opcode != insn_invalid; i++)
+ if (insn_table[i].opcode == opc) {
+ ip = &insn_table[i];
+ break;
+ }
+
+ if (!ip)
+ panic("Unsupported Micro-assembler instruction %d", opc);
+
+ op = ip->match;
+ va_start(ap, opc);
+ if (ip->fields & RS)
+ op |= build_rs(va_arg(ap, u32));
+ if (ip->fields & RT)
+ op |= build_rt(va_arg(ap, u32));
+ if (ip->fields & RD)
+ op |= build_rd(va_arg(ap, u32));
+ if (ip->fields & RE)
+ op |= build_re(va_arg(ap, u32));
+ if (ip->fields & SIMM)
+ op |= build_simm(va_arg(ap, s32));
+ if (ip->fields & UIMM)
+ op |= build_uimm(va_arg(ap, u32));
+ if (ip->fields & BIMM)
+ op |= build_bimm(va_arg(ap, s32));
+ if (ip->fields & JIMM)
+ op |= build_jimm(va_arg(ap, u32));
+ if (ip->fields & FUNC)
+ op |= build_func(va_arg(ap, u32));
+ if (ip->fields & SET)
+ op |= build_set(va_arg(ap, u32));
+ va_end(ap);
+
+ **buf = op;
+ (*buf)++;
+}
+
+#define I_u1u2u3(op) \
+Ip_u1u2u3(op) \
+{ \
+ build_insn(buf, insn##op, a, b, c); \
+}
+
+#define I_u2u1u3(op) \
+Ip_u2u1u3(op) \
+{ \
+ build_insn(buf, insn##op, b, a, c); \
+}
+
+#define I_u3u1u2(op) \
+Ip_u3u1u2(op) \
+{ \
+ build_insn(buf, insn##op, b, c, a); \
+}
+
+#define I_u1u2s3(op) \
+Ip_u1u2s3(op) \
+{ \
+ build_insn(buf, insn##op, a, b, c); \
+}
+
+#define I_u2s3u1(op) \
+Ip_u2s3u1(op) \
+{ \
+ build_insn(buf, insn##op, c, a, b); \
+}
+
+#define I_u2u1s3(op) \
+Ip_u2u1s3(op) \
+{ \
+ build_insn(buf, insn##op, b, a, c); \
+}
+
+#define I_u1u2(op) \
+Ip_u1u2(op) \
+{ \
+ build_insn(buf, insn##op, a, b); \
+}
+
+#define I_u1s2(op) \
+Ip_u1s2(op) \
+{ \
+ build_insn(buf, insn##op, a, b); \
+}
+
+#define I_u1(op) \
+Ip_u1(op) \
+{ \
+ build_insn(buf, insn##op, a); \
+}
+
+#define I_0(op) \
+Ip_0(op) \
+{ \
+ build_insn(buf, insn##op); \
+}
+
+I_u2u1s3(_addiu)
+I_u3u1u2(_addu)
+I_u2u1u3(_andi)
+I_u3u1u2(_and)
+I_u1u2s3(_beq)
+I_u1u2s3(_beql)
+I_u1s2(_bgez)
+I_u1s2(_bgezl)
+I_u1s2(_bltz)
+I_u1s2(_bltzl)
+I_u1u2s3(_bne)
+I_u1u2u3(_dmfc0)
+I_u1u2u3(_dmtc0)
+I_u2u1s3(_daddiu)
+I_u3u1u2(_daddu)
+I_u2u1u3(_dsll)
+I_u2u1u3(_dsll32)
+I_u2u1u3(_dsra)
+I_u2u1u3(_dsrl)
+I_u2u1u3(_dsrl32)
+I_u3u1u2(_dsubu)
+I_0(_eret)
+I_u1(_j)
+I_u1(_jal)
+I_u1(_jr)
+I_u2s3u1(_ld)
+I_u2s3u1(_ll)
+I_u2s3u1(_lld)
+I_u1s2(_lui)
+I_u2s3u1(_lw)
+I_u1u2u3(_mfc0)
+I_u1u2u3(_mtc0)
+I_u2u1u3(_ori)
+I_0(_rfe)
+I_u2s3u1(_sc)
+I_u2s3u1(_scd)
+I_u2s3u1(_sd)
+I_u2u1u3(_sll)
+I_u2u1u3(_sra)
+I_u2u1u3(_srl)
+I_u3u1u2(_subu)
+I_u2s3u1(_sw)
+I_0(_tlbp)
+I_0(_tlbwi)
+I_0(_tlbwr)
+I_u3u1u2(_xor)
+I_u2u1u3(_xori)
+
+/* Handle labels. */
+__init void uasm_build_label(struct uasm_label **lab, u32 *addr, int lid)
+{
+ (*lab)->addr = addr;
+ (*lab)->lab = lid;
+ (*lab)++;
+}
+
+#ifdef CONFIG_64BIT
+__init int uasm_in_compat_space_p(long addr)
+{
+ /* Is this address in 32bit compat space? */
+ return (((addr) & 0xffffffff00000000L) == 0xffffffff00000000L);
+}
+
+__init int uasm_rel_highest(long val)
+{
+ return ((((val + 0x800080008000L) >> 48) & 0xffff) ^ 0x8000) - 0x8000;
+}
+
+__init int uasm_rel_higher(long val)
+{
+ return ((((val + 0x80008000L) >> 32) & 0xffff) ^ 0x8000) - 0x8000;
+}
+#endif
+
+__init int uasm_rel_hi(long val)
+{
+ return ((((val + 0x8000L) >> 16) & 0xffff) ^ 0x8000) - 0x8000;
+}
+
+__init int uasm_rel_lo(long val)
+{
+ return ((val & 0xffff) ^ 0x8000) - 0x8000;
+}
+
+__init void UASM_i_LA_mostly(u32 **buf, unsigned int rs, long addr)
+{
+#ifdef CONFIG_64BIT
+ if (!uasm_in_compat_space_p(addr)) {
+ uasm_i_lui(buf, rs, uasm_rel_highest(addr));
+ if (uasm_rel_higher(addr))
+ uasm_i_daddiu(buf, rs, rs, uasm_rel_higher(addr));
+ if (uasm_rel_hi(addr)) {
+ uasm_i_dsll(buf, rs, rs, 16);
+ uasm_i_daddiu(buf, rs, rs, uasm_rel_hi(addr));
+ uasm_i_dsll(buf, rs, rs, 16);
+ } else
+ uasm_i_dsll32(buf, rs, rs, 0);
+ } else
+#endif
+ uasm_i_lui(buf, rs, uasm_rel_hi(addr));
+}
+
+__init void UASM_i_LA(u32 **buf, unsigned int rs, long addr)
+{
+ UASM_i_LA_mostly(buf, rs, addr);
+ if (uasm_rel_lo(addr))
+ UASM_i_ADDIU(buf, rs, rs, uasm_rel_lo(addr));
+}
+
+/* Handle relocations. */
+__init void
+uasm_r_mips_pc16(struct uasm_reloc **rel, u32 *addr, int lid)
+{
+ (*rel)->addr = addr;
+ (*rel)->type = R_MIPS_PC16;
+ (*rel)->lab = lid;
+ (*rel)++;
+}
+
+static inline void
+__resolve_relocs(struct uasm_reloc *rel, struct uasm_label *lab)
+{
+ long laddr = (long)lab->addr;
+ long raddr = (long)rel->addr;
+
+ switch (rel->type) {
+ case R_MIPS_PC16:
+ *rel->addr |= build_bimm(laddr - (raddr + 4));
+ break;
+
+ default:
+ panic("Unsupported Micro-assembler relocation %d",
+ rel->type);
+ }
+}
+
+__init void
+uasm_resolve_relocs(struct uasm_reloc *rel, struct uasm_label *lab)
+{
+ struct uasm_label *l;
+
+ for (; rel->lab != UASM_LABEL_INVALID; rel++)
+ for (l = lab; l->lab != UASM_LABEL_INVALID; l++)
+ if (rel->lab == l->lab)
+ __resolve_relocs(rel, l);
+}
+
+__init void
+uasm_move_relocs(struct uasm_reloc *rel, u32 *first, u32 *end, long off)
+{
+ for (; rel->lab != UASM_LABEL_INVALID; rel++)
+ if (rel->addr >= first && rel->addr < end)
+ rel->addr += off;
+}
+
+__init void
+uasm_move_labels(struct uasm_label *lab, u32 *first, u32 *end, long off)
+{
+ for (; lab->lab != UASM_LABEL_INVALID; lab++)
+ if (lab->addr >= first && lab->addr < end)
+ lab->addr += off;
+}
+
+__init void
+uasm_copy_handler(struct uasm_reloc *rel, struct uasm_label *lab, u32 *first,
+ u32 *end, u32 *target)
+{
+ long off = (long)(target - first);
+
+ memcpy(target, first, (end - first) * sizeof(u32));
+
+ uasm_move_relocs(rel, first, end, off);
+ uasm_move_labels(lab, first, end, off);
+}
+
+__init int uasm_insn_has_bdelay(struct uasm_reloc *rel, u32 *addr)
+{
+ for (; rel->lab != UASM_LABEL_INVALID; rel++) {
+ if (rel->addr == addr
+ && (rel->type == R_MIPS_PC16
+ || rel->type == R_MIPS_26))
+ return 1;
+ }
+
+ return 0;
+}
+
+/* Convenience functions for labeled branches. */
+void __init
+uasm_il_bltz(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid)
+{
+ uasm_r_mips_pc16(r, *p, lid);
+ uasm_i_bltz(p, reg, 0);
+}
+
+void __init
+uasm_il_b(u32 **p, struct uasm_reloc **r, int lid)
+{
+ uasm_r_mips_pc16(r, *p, lid);
+ uasm_i_b(p, 0);
+}
+
+void __init
+uasm_il_beqz(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid)
+{
+ uasm_r_mips_pc16(r, *p, lid);
+ uasm_i_beqz(p, reg, 0);
+}
+
+void __init
+uasm_il_beqzl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid)
+{
+ uasm_r_mips_pc16(r, *p, lid);
+ uasm_i_beqzl(p, reg, 0);
+}
+
+void __init
+uasm_il_bnez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid)
+{
+ uasm_r_mips_pc16(r, *p, lid);
+ uasm_i_bnez(p, reg, 0);
+}
+
+void __init
+uasm_il_bgezl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid)
+{
+ uasm_r_mips_pc16(r, *p, lid);
+ uasm_i_bgezl(p, reg, 0);
+}
+
+void __init
+uasm_il_bgez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid)
+{
+ uasm_r_mips_pc16(r, *p, lid);
+ uasm_i_bgez(p, reg, 0);
+}
diff --git a/arch/mips/mm/uasm.h b/arch/mips/mm/uasm.h
new file mode 100644
index 0000000..e0053b0
--- /dev/null
+++ b/arch/mips/mm/uasm.h
@@ -0,0 +1,192 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2004,2005,2006,2008 Thiemo Seufer
+ * Copyright (C) 2005 Maciej W. Rozycki
+ * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org)
+ */
+
+#include <linux/types.h>
+
+#define Ip_u1u2u3(op) \
+void __init \
+uasm_i##op(u32 **buf, unsigned int a, unsigned int b, unsigned int c)
+
+#define Ip_u2u1u3(op) \
+void __init \
+uasm_i##op(u32 **buf, unsigned int a, unsigned int b, unsigned int c)
+
+#define Ip_u3u1u2(op) \
+void __init \
+uasm_i##op(u32 **buf, unsigned int a, unsigned int b, unsigned int c)
+
+#define Ip_u1u2s3(op) \
+void __init \
+uasm_i##op(u32 **buf, unsigned int a, unsigned int b, signed int c)
+
+#define Ip_u2s3u1(op) \
+void __init \
+uasm_i##op(u32 **buf, unsigned int a, signed int b, unsigned int c)
+
+#define Ip_u2u1s3(op) \
+void __init \
+uasm_i##op(u32 **buf, unsigned int a, unsigned int b, signed int c)
+
+#define Ip_u1u2(op) \
+void __init uasm_i##op(u32 **buf, unsigned int a, unsigned int b)
+
+#define Ip_u1s2(op) \
+void __init uasm_i##op(u32 **buf, unsigned int a, signed int b)
+
+#define Ip_u1(op) void __init uasm_i##op(u32 **buf, unsigned int a)
+
+#define Ip_0(op) void __init uasm_i##op(u32 **buf)
+
+Ip_u2u1s3(_addiu);
+Ip_u3u1u2(_addu);
+Ip_u2u1u3(_andi);
+Ip_u3u1u2(_and);
+Ip_u1u2s3(_beq);
+Ip_u1u2s3(_beql);
+Ip_u1s2(_bgez);
+Ip_u1s2(_bgezl);
+Ip_u1s2(_bltz);
+Ip_u1s2(_bltzl);
+Ip_u1u2s3(_bne);
+Ip_u1u2u3(_dmfc0);
+Ip_u1u2u3(_dmtc0);
+Ip_u2u1s3(_daddiu);
+Ip_u3u1u2(_daddu);
+Ip_u2u1u3(_dsll);
+Ip_u2u1u3(_dsll32);
+Ip_u2u1u3(_dsra);
+Ip_u2u1u3(_dsrl);
+Ip_u2u1u3(_dsrl32);
+Ip_u3u1u2(_dsubu);
+Ip_0(_eret);
+Ip_u1(_j);
+Ip_u1(_jal);
+Ip_u1(_jr);
+Ip_u2s3u1(_ld);
+Ip_u2s3u1(_ll);
+Ip_u2s3u1(_lld);
+Ip_u1s2(_lui);
+Ip_u2s3u1(_lw);
+Ip_u1u2u3(_mfc0);
+Ip_u1u2u3(_mtc0);
+Ip_u2u1u3(_ori);
+Ip_0(_rfe);
+Ip_u2s3u1(_sc);
+Ip_u2s3u1(_scd);
+Ip_u2s3u1(_sd);
+Ip_u2u1u3(_sll);
+Ip_u2u1u3(_sra);
+Ip_u2u1u3(_srl);
+Ip_u3u1u2(_subu);
+Ip_u2s3u1(_sw);
+Ip_0(_tlbp);
+Ip_0(_tlbwi);
+Ip_0(_tlbwr);
+Ip_u3u1u2(_xor);
+Ip_u2u1u3(_xori);
+
+/* Handle labels. */
+struct uasm_label {
+ u32 *addr;
+ int lab;
+};
+
+__init void uasm_build_label(struct uasm_label **lab, u32 *addr, int lid);
+#ifdef CONFIG_64BIT
+__init int uasm_in_compat_space_p(long addr);
+__init int uasm_rel_highest(long val);
+__init int uasm_rel_higher(long val);
+#endif
+__init int uasm_rel_hi(long val);
+__init int uasm_rel_lo(long val);
+__init void UASM_i_LA_mostly(u32 **buf, unsigned int rs, long addr);
+__init void UASM_i_LA(u32 **buf, unsigned int rs, long addr);
+
+#define UASM_L_LA(lb) \
+static inline void uasm_l##lb(struct uasm_label **lab, u32 *addr) \
+{ \
+ uasm_build_label(lab, addr, label##lb); \
+}
+
+/* convenience macros for instructions */
+#ifdef CONFIG_64BIT
+# define UASM_i_LW(buf, rs, rt, off) uasm_i_ld(buf, rs, rt, off)
+# define UASM_i_SW(buf, rs, rt, off) uasm_i_sd(buf, rs, rt, off)
+# define UASM_i_SLL(buf, rs, rt, sh) uasm_i_dsll(buf, rs, rt, sh)
+# define UASM_i_SRA(buf, rs, rt, sh) uasm_i_dsra(buf, rs, rt, sh)
+# define UASM_i_SRL(buf, rs, rt, sh) uasm_i_dsrl(buf, rs, rt, sh)
+# define UASM_i_MFC0(buf, rt, rd...) uasm_i_dmfc0(buf, rt, rd)
+# define UASM_i_MTC0(buf, rt, rd...) uasm_i_dmtc0(buf, rt, rd)
+# define UASM_i_ADDIU(buf, rs, rt, val) uasm_i_daddiu(buf, rs, rt, val)
+# define UASM_i_ADDU(buf, rs, rt, rd) uasm_i_daddu(buf, rs, rt, rd)
+# define UASM_i_SUBU(buf, rs, rt, rd) uasm_i_dsubu(buf, rs, rt, rd)
+# define UASM_i_LL(buf, rs, rt, off) uasm_i_lld(buf, rs, rt, off)
+# define UASM_i_SC(buf, rs, rt, off) uasm_i_scd(buf, rs, rt, off)
+#else
+# define UASM_i_LW(buf, rs, rt, off) uasm_i_lw(buf, rs, rt, off)
+# define UASM_i_SW(buf, rs, rt, off) uasm_i_sw(buf, rs, rt, off)
+# define UASM_i_SLL(buf, rs, rt, sh) uasm_i_sll(buf, rs, rt, sh)
+# define UASM_i_SRA(buf, rs, rt, sh) uasm_i_sra(buf, rs, rt, sh)
+# define UASM_i_SRL(buf, rs, rt, sh) uasm_i_srl(buf, rs, rt, sh)
+# define UASM_i_MFC0(buf, rt, rd...) uasm_i_mfc0(buf, rt, rd)
+# define UASM_i_MTC0(buf, rt, rd...) uasm_i_mtc0(buf, rt, rd)
+# define UASM_i_ADDIU(buf, rs, rt, val) uasm_i_addiu(buf, rs, rt, val)
+# define UASM_i_ADDU(buf, rs, rt, rd) uasm_i_addu(buf, rs, rt, rd)
+# define UASM_i_SUBU(buf, rs, rt, rd) uasm_i_subu(buf, rs, rt, rd)
+# define UASM_i_LL(buf, rs, rt, off) uasm_i_ll(buf, rs, rt, off)
+# define UASM_i_SC(buf, rs, rt, off) uasm_i_sc(buf, rs, rt, off)
+#endif
+
+#define uasm_i_b(buf, off) uasm_i_beq(buf, 0, 0, off)
+#define uasm_i_beqz(buf, rs, off) uasm_i_beq(buf, rs, 0, off)
+#define uasm_i_beqzl(buf, rs, off) uasm_i_beql(buf, rs, 0, off)
+#define uasm_i_bnez(buf, rs, off) uasm_i_bne(buf, rs, 0, off)
+#define uasm_i_bnezl(buf, rs, off) uasm_i_bnel(buf, rs, 0, off)
+#define uasm_i_move(buf, a, b) UASM_i_ADDU(buf, a, 0, b)
+#define uasm_i_nop(buf) uasm_i_sll(buf, 0, 0, 0)
+#define uasm_i_ssnop(buf) uasm_i_sll(buf, 0, 0, 1)
+#define uasm_i_ehb(buf) uasm_i_sll(buf, 0, 0, 3)
+
+/* Handle relocations. */
+struct uasm_reloc {
+ u32 *addr;
+ unsigned int type;
+ int lab;
+};
+
+/* This is zero so we can use zeroed label arrays. */
+#define UASM_LABEL_INVALID 0
+
+__init void uasm_r_mips_pc16(struct uasm_reloc **rel, u32 *addr, int lid);
+__init void
+uasm_resolve_relocs(struct uasm_reloc *rel, struct uasm_label *lab);
+__init void
+uasm_move_relocs(struct uasm_reloc *rel, u32 *first, u32 *end, long off);
+__init void
+uasm_move_labels(struct uasm_label *lab, u32 *first, u32 *end, long off);
+__init void
+uasm_copy_handler(struct uasm_reloc *rel, struct uasm_label *lab, u32 *first,
+ u32 *end, u32 *target);
+__init int uasm_insn_has_bdelay(struct uasm_reloc *rel, u32 *addr);
+
+/* Convenience functions for labeled branches. */
+void __init
+uasm_il_bltz(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
+void __init uasm_il_b(u32 **p, struct uasm_reloc **r, int lid);
+void __init
+uasm_il_beqz(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
+void __init
+uasm_il_beqzl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
+void __init
+uasm_il_bnez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
+void __init
+uasm_il_bgezl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
+void __init
+uasm_il_bgez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
^ permalink raw reply related [flat|nested] 38+ messages in thread
* Re: your mail
2008-01-22 0:00 (no subject) Thiemo Seufer
@ 2008-01-28 17:51 ` Ralf Baechle
2008-01-28 20:05 ` Split the micro-assembler from tlbex.c (was: Re: your mail) Thiemo Seufer
0 siblings, 1 reply; 38+ messages in thread
From: Ralf Baechle @ 2008-01-28 17:51 UTC (permalink / raw)
To: Thiemo Seufer; +Cc: linux-mips
On Tue, Jan 22, 2008 at 12:00:26AM +0000, Thiemo Seufer wrote:
> This patch moves the micro-assembler in a separate implementation, as
> it is useful for further run-time optimizations. The only change in
> behaviour is cutting down printk noise at kernel startup time.
>
> Checkpatch complains about macro parameters which aren't protected by
> parentheses. I believe this is a flaw in checkpatch, the paste operator
> used in those macros won't work with parenthesised parameters.
>
> Tested on:
> - Qemu 32-bit little endian
> - BCM1480 64-bit big endian
>
>
> Thiemo
>
>
> ---
> Split the micro-assembler from tlbex.c.
>
> Signed-off-by: Thiemo Seufer <ths@networkno.de>
Looks technically ok but conflicts with these 7 other patches which also
touch arch/mips/mm/tlbex.c:
Please keep all the stuff the stuff that should go into the commit
message - and only that - above the "---" tearline. git-am will drop
anything below it and friendly greetings, signatures etc. should not go
into the log message so keep that below the tearoff line.
commit 699a78e99f302003ae6d6090bf7f35eb69b772e0
Author: Manuel Lauss <mano@roarinelk.homelinux.net>
Date: Thu Dec 6 09:07:55 2007 +0100
[MIPS] Alchemy: Au1210/Au1250 CPU support
This patch adds IDs for new Au1200 variants: Au1210 and Au1250.
They are essentially identical to the Au1200 except for the Au1210
which has a different SoC-ID in the PRId register [bits 31:24].
The Au1250 is a "Au1200 V0.2".
Signed-off-by: Manuel Lauss <mano@roarinelk.homelinux.net>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
commit 56bccd5921f7b1160ddab0f9c3e9cc227ecd9aef
Author: Franck Bui-Huu <fbuihuu@gmail.com>
Date: Thu Oct 18 09:11:17 2007 +0200
[MIPS] tlbex.c: cleanup debug code
Signed-off-by: Franck Bui-Huu <fbuihuu@gmail.com>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
commit 97432dc56d464006a62b1cd3ee6484828bde816c
Author: Franck Bui-Huu <fbuihuu@gmail.com>
Date: Thu Oct 18 09:11:16 2007 +0200
[MIPS] tlbex.c: use __cacheline_aligned instead of __tlb_handler_align
Signed-off-by: Franck Bui-Huu <fbuihuu@gmail.com>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
commit 82e27810cd28e4322bd400640c8627ceacfc29f5
Author: Franck Bui-Huu <fbuihuu@gmail.com>
Date: Thu Oct 18 09:11:15 2007 +0200
[MIPS] tlbex.c: cleanup include files
Signed-off-by: Franck Bui-Huu <fbuihuu@gmail.com>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
commit b849ac81b87278c9b9e17aef8f4d82a30578ec93
Author: Franck Bui-Huu <fbuihuu@gmail.com>
Date: Thu Oct 18 09:11:14 2007 +0200
[MIPS] tlbex.c: Cleanup __init usages.
Signed-off-by: Franck Bui-Huu <fbuihuu@gmail.com>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
commit bf672b2f700d031d933c7dadcd9fae5edaa019b4
Author: Maciej W. Rozycki <macro@linux-mips.org>
Date: Tue Oct 23 12:43:25 2007 +0100
[MIPS] R4000/R4400 daddiu erratum workaround
This complements the generic R4000/R4400 errata workaround code and adds
bits for the daddiu problem. In most places it just modifies handwritten
assembly code so that the assembler is allowed to use a temporary register
as daddiu may now be treated as a macro that expands to a sequence of li
and daddu. It is the AT register or, where AT is unavailable or used
explicitly for another purpose, an explicitly-named register is selected,
using the .set at=<reg> feature added recently to gas. This feature is
only used if CONFIG_CPU_DADDI_WORKAROUNDS has been set, so if the
workaround remains disabled, the required version of binutils stays
unchanged.
Similarly, daddiu instructions put in branch delay slots in noreorder
fragments are now taken out of them and the assembler is allowed to
reorder them itself as possible (which it does making the whole idea of
scheduling them into delay slots manually questionable).
Also in the very few places where such a simple conversion was not
possible, a handcoded longer sequence is implemented.
Other than that there are changes to code responsible for building the
TLB fault and page clear/copy handlers to avoid daddiu as appropriate.
These are only effective if the erratum is verified to be present at the
run time.
Finally there is a trivial update to __delay(), because it uses daddiu in
a branch delay slot.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
commit 2d220349159729f143570673f8752aafd6d8da74
Author: Ralf Baechle <ralf@linux-mips.org>
Date: Mon Jan 28 17:14:10 2008 +0000
[MIPS] tlbex: Cleanup handling of R2 hazards in TLB handlers.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
But I'm really happing to see the generalization we've been talking about
to finally proceed.
Ralf
^ permalink raw reply [flat|nested] 38+ messages in thread
* Split the micro-assembler from tlbex.c (was: Re: your mail)
2008-01-28 17:51 ` your mail Ralf Baechle
@ 2008-01-28 20:05 ` Thiemo Seufer
2008-01-28 22:53 ` Ralf Baechle
0 siblings, 1 reply; 38+ messages in thread
From: Thiemo Seufer @ 2008-01-28 20:05 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Ralf Baechle wrote:
> On Tue, Jan 22, 2008 at 12:00:26AM +0000, Thiemo Seufer wrote:
>
> > This patch moves the micro-assembler in a separate implementation, as
> > it is useful for further run-time optimizations. The only change in
> > behaviour is cutting down printk noise at kernel startup time.
> >
> > Checkpatch complains about macro parameters which aren't protected by
> > parentheses. I believe this is a flaw in checkpatch, the paste operator
> > used in those macros won't work with parenthesised parameters.
> >
> > Tested on:
> > - Qemu 32-bit little endian
> > - BCM1480 64-bit big endian
> >
> >
> > Thiemo
> >
> >
> > ---
> > Split the micro-assembler from tlbex.c.
> >
> > Signed-off-by: Thiemo Seufer <ths@networkno.de>
>
> Looks technically ok but conflicts with these 7 other patches which also
> touch arch/mips/mm/tlbex.c:
>
> Please keep all the stuff the stuff that should go into the commit
> message - and only that - above the "---" tearline. git-am will drop
> anything below it and friendly greetings, signatures etc. should not go
> into the log message so keep that below the tearoff line.
Split the micro-assembler from tlbex.c.
This patch moves the micro-assembler in a separate implementation, as
it is useful for further run-time optimizations. The only change in
behaviour is cutting down printk noise at kernel startup time.
Checkpatch complains about macro parameters which aren't protected by
parentheses. I believe this is a flaw in checkpatch, the paste operator
used in those macros won't work with parenthesised parameters.
Signed-off-by: Thiemo Seufer <ths@networkno.de>
---
diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile
index 32fd5db..c6f832e 100644
--- a/arch/mips/mm/Makefile
+++ b/arch/mips/mm/Makefile
@@ -3,7 +3,8 @@
#
obj-y += cache.o dma-default.o extable.o fault.o \
- init.o pgtable.o tlbex.o tlbex-fault.o
+ init.o pgtable.o tlbex.o tlbex-fault.o \
+ uasm.o
obj-$(CONFIG_32BIT) += ioremap.o pgtable-32.o
obj-$(CONFIG_64BIT) += pgtable-64.o
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index d026302..218a6cc 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -5,7 +5,7 @@
*
* Synthesize TLB refill handlers at runtime.
*
- * Copyright (C) 2004,2005,2006 by Thiemo Seufer
+ * Copyright (C) 2004, 2005, 2006, 2008 Thiemo Seufer
* Copyright (C) 2005, 2007 Maciej W. Rozycki
* Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org)
*
@@ -24,12 +24,11 @@
#include <linux/string.h>
#include <linux/init.h>
-#include <asm/bugs.h>
#include <asm/mmu_context.h>
-#include <asm/inst.h>
-#include <asm/elf.h>
#include <asm/war.h>
+#include "uasm.h"
+
static inline int r45k_bvahwbug(void)
{
/* XXX: We should probe for the presence of this bug, but we don't. */
@@ -67,371 +66,9 @@ static int __init m4kc_tlbp_war(void)
(PRID_COMP_MIPS | PRID_IMP_4KC);
}
-/*
- * A little micro-assembler, intended for TLB refill handler
- * synthesizing. It is intentionally kept simple, does only support
- * a subset of instructions, and does not try to hide pipeline effects
- * like branch delay slots.
- */
-
-enum fields
-{
- RS = 0x001,
- RT = 0x002,
- RD = 0x004,
- RE = 0x008,
- SIMM = 0x010,
- UIMM = 0x020,
- BIMM = 0x040,
- JIMM = 0x080,
- FUNC = 0x100,
- SET = 0x200
-};
-
-#define OP_MASK 0x3f
-#define OP_SH 26
-#define RS_MASK 0x1f
-#define RS_SH 21
-#define RT_MASK 0x1f
-#define RT_SH 16
-#define RD_MASK 0x1f
-#define RD_SH 11
-#define RE_MASK 0x1f
-#define RE_SH 6
-#define IMM_MASK 0xffff
-#define IMM_SH 0
-#define JIMM_MASK 0x3ffffff
-#define JIMM_SH 0
-#define FUNC_MASK 0x3f
-#define FUNC_SH 0
-#define SET_MASK 0x7
-#define SET_SH 0
-
-enum opcode {
- insn_invalid,
- insn_addu, insn_addiu, insn_and, insn_andi, insn_beq,
- insn_beql, insn_bgez, insn_bgezl, insn_bltz, insn_bltzl,
- insn_bne, insn_daddu, insn_daddiu, insn_dmfc0, insn_dmtc0,
- insn_dsll, insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32,
- insn_dsubu, insn_eret, insn_j, insn_jal, insn_jr, insn_ld,
- insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0, insn_mtc0,
- insn_ori, insn_rfe, insn_sc, insn_scd, insn_sd, insn_sll,
- insn_sra, insn_srl, insn_subu, insn_sw, insn_tlbp, insn_tlbwi,
- insn_tlbwr, insn_xor, insn_xori
-};
-
-struct insn {
- enum opcode opcode;
- u32 match;
- enum fields fields;
-};
-
-/* This macro sets the non-variable bits of an instruction. */
-#define M(a, b, c, d, e, f) \
- ((a) << OP_SH \
- | (b) << RS_SH \
- | (c) << RT_SH \
- | (d) << RD_SH \
- | (e) << RE_SH \
- | (f) << FUNC_SH)
-
-static struct insn insn_table[] __initdata = {
- { insn_addiu, M(addiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
- { insn_addu, M(spec_op, 0, 0, 0, 0, addu_op), RS | RT | RD },
- { insn_and, M(spec_op, 0, 0, 0, 0, and_op), RS | RT | RD },
- { insn_andi, M(andi_op, 0, 0, 0, 0, 0), RS | RT | UIMM },
- { insn_beq, M(beq_op, 0, 0, 0, 0, 0), RS | RT | BIMM },
- { insn_beql, M(beql_op, 0, 0, 0, 0, 0), RS | RT | BIMM },
- { insn_bgez, M(bcond_op, 0, bgez_op, 0, 0, 0), RS | BIMM },
- { insn_bgezl, M(bcond_op, 0, bgezl_op, 0, 0, 0), RS | BIMM },
- { insn_bltz, M(bcond_op, 0, bltz_op, 0, 0, 0), RS | BIMM },
- { insn_bltzl, M(bcond_op, 0, bltzl_op, 0, 0, 0), RS | BIMM },
- { insn_bne, M(bne_op, 0, 0, 0, 0, 0), RS | RT | BIMM },
- { insn_daddiu, M(daddiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
- { insn_daddu, M(spec_op, 0, 0, 0, 0, daddu_op), RS | RT | RD },
- { insn_dmfc0, M(cop0_op, dmfc_op, 0, 0, 0, 0), RT | RD | SET},
- { insn_dmtc0, M(cop0_op, dmtc_op, 0, 0, 0, 0), RT | RD | SET},
- { insn_dsll, M(spec_op, 0, 0, 0, 0, dsll_op), RT | RD | RE },
- { insn_dsll32, M(spec_op, 0, 0, 0, 0, dsll32_op), RT | RD | RE },
- { insn_dsra, M(spec_op, 0, 0, 0, 0, dsra_op), RT | RD | RE },
- { insn_dsrl, M(spec_op, 0, 0, 0, 0, dsrl_op), RT | RD | RE },
- { insn_dsrl32, M(spec_op, 0, 0, 0, 0, dsrl32_op), RT | RD | RE },
- { insn_dsubu, M(spec_op, 0, 0, 0, 0, dsubu_op), RS | RT | RD },
- { insn_eret, M(cop0_op, cop_op, 0, 0, 0, eret_op), 0 },
- { insn_j, M(j_op, 0, 0, 0, 0, 0), JIMM },
- { insn_jal, M(jal_op, 0, 0, 0, 0, 0), JIMM },
- { insn_jr, M(spec_op, 0, 0, 0, 0, jr_op), RS },
- { insn_ld, M(ld_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
- { insn_ll, M(ll_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
- { insn_lld, M(lld_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
- { insn_lui, M(lui_op, 0, 0, 0, 0, 0), RT | SIMM },
- { insn_lw, M(lw_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
- { insn_mfc0, M(cop0_op, mfc_op, 0, 0, 0, 0), RT | RD | SET},
- { insn_mtc0, M(cop0_op, mtc_op, 0, 0, 0, 0), RT | RD | SET},
- { insn_ori, M(ori_op, 0, 0, 0, 0, 0), RS | RT | UIMM },
- { insn_rfe, M(cop0_op, cop_op, 0, 0, 0, rfe_op), 0 },
- { insn_sc, M(sc_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
- { insn_scd, M(scd_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
- { insn_sd, M(sd_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
- { insn_sll, M(spec_op, 0, 0, 0, 0, sll_op), RT | RD | RE },
- { insn_sra, M(spec_op, 0, 0, 0, 0, sra_op), RT | RD | RE },
- { insn_srl, M(spec_op, 0, 0, 0, 0, srl_op), RT | RD | RE },
- { insn_subu, M(spec_op, 0, 0, 0, 0, subu_op), RS | RT | RD },
- { insn_sw, M(sw_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
- { insn_tlbp, M(cop0_op, cop_op, 0, 0, 0, tlbp_op), 0 },
- { insn_tlbwi, M(cop0_op, cop_op, 0, 0, 0, tlbwi_op), 0 },
- { insn_tlbwr, M(cop0_op, cop_op, 0, 0, 0, tlbwr_op), 0 },
- { insn_xor, M(spec_op, 0, 0, 0, 0, xor_op), RS | RT | RD },
- { insn_xori, M(xori_op, 0, 0, 0, 0, 0), RS | RT | UIMM },
- { insn_invalid, 0, 0 }
-};
-
-#undef M
-
-static u32 __init build_rs(u32 arg)
-{
- if (arg & ~RS_MASK)
- printk(KERN_WARNING "TLB synthesizer field overflow\n");
-
- return (arg & RS_MASK) << RS_SH;
-}
-
-static u32 __init build_rt(u32 arg)
-{
- if (arg & ~RT_MASK)
- printk(KERN_WARNING "TLB synthesizer field overflow\n");
-
- return (arg & RT_MASK) << RT_SH;
-}
-
-static u32 __init build_rd(u32 arg)
-{
- if (arg & ~RD_MASK)
- printk(KERN_WARNING "TLB synthesizer field overflow\n");
-
- return (arg & RD_MASK) << RD_SH;
-}
-
-static u32 __init build_re(u32 arg)
-{
- if (arg & ~RE_MASK)
- printk(KERN_WARNING "TLB synthesizer field overflow\n");
-
- return (arg & RE_MASK) << RE_SH;
-}
-
-static u32 __init build_simm(s32 arg)
-{
- if (arg > 0x7fff || arg < -0x8000)
- printk(KERN_WARNING "TLB synthesizer field overflow\n");
-
- return arg & 0xffff;
-}
-
-static u32 __init build_uimm(u32 arg)
-{
- if (arg & ~IMM_MASK)
- printk(KERN_WARNING "TLB synthesizer field overflow\n");
-
- return arg & IMM_MASK;
-}
-
-static u32 __init build_bimm(s32 arg)
-{
- if (arg > 0x1ffff || arg < -0x20000)
- printk(KERN_WARNING "TLB synthesizer field overflow\n");
-
- if (arg & 0x3)
- printk(KERN_WARNING "Invalid TLB synthesizer branch target\n");
-
- return ((arg < 0) ? (1 << 15) : 0) | ((arg >> 2) & 0x7fff);
-}
-
-static u32 __init build_jimm(u32 arg)
-{
- if (arg & ~((JIMM_MASK) << 2))
- printk(KERN_WARNING "TLB synthesizer field overflow\n");
-
- return (arg >> 2) & JIMM_MASK;
-}
-
-static u32 __init build_func(u32 arg)
-{
- if (arg & ~FUNC_MASK)
- printk(KERN_WARNING "TLB synthesizer field overflow\n");
-
- return arg & FUNC_MASK;
-}
-
-static u32 __init build_set(u32 arg)
-{
- if (arg & ~SET_MASK)
- printk(KERN_WARNING "TLB synthesizer field overflow\n");
-
- return arg & SET_MASK;
-}
-
-/*
- * The order of opcode arguments is implicitly left to right,
- * starting with RS and ending with FUNC or IMM.
- */
-static void __init build_insn(u32 **buf, enum opcode opc, ...)
-{
- struct insn *ip = NULL;
- unsigned int i;
- va_list ap;
- u32 op;
-
- for (i = 0; insn_table[i].opcode != insn_invalid; i++)
- if (insn_table[i].opcode == opc) {
- ip = &insn_table[i];
- break;
- }
-
- if (!ip || (opc == insn_daddiu && r4k_daddiu_bug()))
- panic("Unsupported TLB synthesizer instruction %d", opc);
-
- op = ip->match;
- va_start(ap, opc);
- if (ip->fields & RS) op |= build_rs(va_arg(ap, u32));
- if (ip->fields & RT) op |= build_rt(va_arg(ap, u32));
- if (ip->fields & RD) op |= build_rd(va_arg(ap, u32));
- if (ip->fields & RE) op |= build_re(va_arg(ap, u32));
- if (ip->fields & SIMM) op |= build_simm(va_arg(ap, s32));
- if (ip->fields & UIMM) op |= build_uimm(va_arg(ap, u32));
- if (ip->fields & BIMM) op |= build_bimm(va_arg(ap, s32));
- if (ip->fields & JIMM) op |= build_jimm(va_arg(ap, u32));
- if (ip->fields & FUNC) op |= build_func(va_arg(ap, u32));
- if (ip->fields & SET) op |= build_set(va_arg(ap, u32));
- va_end(ap);
-
- **buf = op;
- (*buf)++;
-}
-
-#define I_u1u2u3(op) \
- static void __init __maybe_unused i##op(u32 **buf, unsigned int a, \
- unsigned int b, unsigned int c) \
- { \
- build_insn(buf, insn##op, a, b, c); \
- }
-
-#define I_u2u1u3(op) \
- static void __init __maybe_unused i##op(u32 **buf, unsigned int a, \
- unsigned int b, unsigned int c) \
- { \
- build_insn(buf, insn##op, b, a, c); \
- }
-
-#define I_u3u1u2(op) \
- static void __init __maybe_unused i##op(u32 **buf, unsigned int a, \
- unsigned int b, unsigned int c) \
- { \
- build_insn(buf, insn##op, b, c, a); \
- }
-
-#define I_u1u2s3(op) \
- static void __init __maybe_unused i##op(u32 **buf, unsigned int a, \
- unsigned int b, signed int c) \
- { \
- build_insn(buf, insn##op, a, b, c); \
- }
-
-#define I_u2s3u1(op) \
- static void __init __maybe_unused i##op(u32 **buf, unsigned int a, \
- signed int b, unsigned int c) \
- { \
- build_insn(buf, insn##op, c, a, b); \
- }
-
-#define I_u2u1s3(op) \
- static void __init __maybe_unused i##op(u32 **buf, unsigned int a, \
- unsigned int b, signed int c) \
- { \
- build_insn(buf, insn##op, b, a, c); \
- }
-
-#define I_u1u2(op) \
- static void __init __maybe_unused i##op(u32 **buf, unsigned int a, \
- unsigned int b) \
- { \
- build_insn(buf, insn##op, a, b); \
- }
-
-#define I_u1s2(op) \
- static void __init __maybe_unused i##op(u32 **buf, unsigned int a, \
- signed int b) \
- { \
- build_insn(buf, insn##op, a, b); \
- }
-
-#define I_u1(op) \
- static void __init __maybe_unused i##op(u32 **buf, unsigned int a) \
- { \
- build_insn(buf, insn##op, a); \
- }
-
-#define I_0(op) \
- static void __init __maybe_unused i##op(u32 **buf) \
- { \
- build_insn(buf, insn##op); \
- }
-
-I_u2u1s3(_addiu);
-I_u3u1u2(_addu);
-I_u2u1u3(_andi);
-I_u3u1u2(_and);
-I_u1u2s3(_beq);
-I_u1u2s3(_beql);
-I_u1s2(_bgez);
-I_u1s2(_bgezl);
-I_u1s2(_bltz);
-I_u1s2(_bltzl);
-I_u1u2s3(_bne);
-I_u1u2u3(_dmfc0);
-I_u1u2u3(_dmtc0);
-I_u2u1s3(_daddiu);
-I_u3u1u2(_daddu);
-I_u2u1u3(_dsll);
-I_u2u1u3(_dsll32);
-I_u2u1u3(_dsra);
-I_u2u1u3(_dsrl);
-I_u2u1u3(_dsrl32);
-I_u3u1u2(_dsubu);
-I_0(_eret);
-I_u1(_j);
-I_u1(_jal);
-I_u1(_jr);
-I_u2s3u1(_ld);
-I_u2s3u1(_ll);
-I_u2s3u1(_lld);
-I_u1s2(_lui);
-I_u2s3u1(_lw);
-I_u1u2u3(_mfc0);
-I_u1u2u3(_mtc0);
-I_u2u1u3(_ori);
-I_0(_rfe);
-I_u2s3u1(_sc);
-I_u2s3u1(_scd);
-I_u2s3u1(_sd);
-I_u2u1u3(_sll);
-I_u2u1u3(_sra);
-I_u2u1u3(_srl);
-I_u3u1u2(_subu);
-I_u2s3u1(_sw);
-I_0(_tlbp);
-I_0(_tlbwi);
-I_0(_tlbwr);
-I_u3u1u2(_xor)
-I_u2u1u3(_xori);
-
-/*
- * handling labels
- */
-
+/* Handle labels (which must be positive integers). */
enum label_id {
- label_invalid,
- label_second_part,
+ label_second_part = 1,
label_leave,
#ifdef MODULE_START
label_module_alloc,
@@ -447,278 +84,20 @@ enum label_id {
label_r3000_write_probe_fail,
};
-struct label {
- u32 *addr;
- enum label_id lab;
-};
-
-static void __init build_label(struct label **lab, u32 *addr,
- enum label_id l)
-{
- (*lab)->addr = addr;
- (*lab)->lab = l;
- (*lab)++;
-}
-
-#define L_LA(lb) \
- static inline void __init l##lb(struct label **lab, u32 *addr) \
- { \
- build_label(lab, addr, label##lb); \
- }
-
-L_LA(_second_part)
-L_LA(_leave)
+UASM_L_LA(_second_part)
+UASM_L_LA(_leave)
#ifdef MODULE_START
-L_LA(_module_alloc)
-#endif
-L_LA(_vmalloc)
-L_LA(_vmalloc_done)
-L_LA(_tlbw_hazard)
-L_LA(_split)
-L_LA(_nopage_tlbl)
-L_LA(_nopage_tlbs)
-L_LA(_nopage_tlbm)
-L_LA(_smp_pgtable_change)
-L_LA(_r3000_write_probe_fail)
-
-/* convenience macros for instructions */
-#ifdef CONFIG_64BIT
-# define i_LW(buf, rs, rt, off) i_ld(buf, rs, rt, off)
-# define i_SW(buf, rs, rt, off) i_sd(buf, rs, rt, off)
-# define i_SLL(buf, rs, rt, sh) i_dsll(buf, rs, rt, sh)
-# define i_SRA(buf, rs, rt, sh) i_dsra(buf, rs, rt, sh)
-# define i_SRL(buf, rs, rt, sh) i_dsrl(buf, rs, rt, sh)
-# define i_MFC0(buf, rt, rd...) i_dmfc0(buf, rt, rd)
-# define i_MTC0(buf, rt, rd...) i_dmtc0(buf, rt, rd)
-# define i_ADDIU(buf, rs, rt, val) i_daddiu(buf, rs, rt, val)
-# define i_ADDU(buf, rs, rt, rd) i_daddu(buf, rs, rt, rd)
-# define i_SUBU(buf, rs, rt, rd) i_dsubu(buf, rs, rt, rd)
-# define i_LL(buf, rs, rt, off) i_lld(buf, rs, rt, off)
-# define i_SC(buf, rs, rt, off) i_scd(buf, rs, rt, off)
-#else
-# define i_LW(buf, rs, rt, off) i_lw(buf, rs, rt, off)
-# define i_SW(buf, rs, rt, off) i_sw(buf, rs, rt, off)
-# define i_SLL(buf, rs, rt, sh) i_sll(buf, rs, rt, sh)
-# define i_SRA(buf, rs, rt, sh) i_sra(buf, rs, rt, sh)
-# define i_SRL(buf, rs, rt, sh) i_srl(buf, rs, rt, sh)
-# define i_MFC0(buf, rt, rd...) i_mfc0(buf, rt, rd)
-# define i_MTC0(buf, rt, rd...) i_mtc0(buf, rt, rd)
-# define i_ADDIU(buf, rs, rt, val) i_addiu(buf, rs, rt, val)
-# define i_ADDU(buf, rs, rt, rd) i_addu(buf, rs, rt, rd)
-# define i_SUBU(buf, rs, rt, rd) i_subu(buf, rs, rt, rd)
-# define i_LL(buf, rs, rt, off) i_ll(buf, rs, rt, off)
-# define i_SC(buf, rs, rt, off) i_sc(buf, rs, rt, off)
-#endif
-
-#define i_b(buf, off) i_beq(buf, 0, 0, off)
-#define i_beqz(buf, rs, off) i_beq(buf, rs, 0, off)
-#define i_beqzl(buf, rs, off) i_beql(buf, rs, 0, off)
-#define i_bnez(buf, rs, off) i_bne(buf, rs, 0, off)
-#define i_bnezl(buf, rs, off) i_bnel(buf, rs, 0, off)
-#define i_move(buf, a, b) i_ADDU(buf, a, 0, b)
-#define i_nop(buf) i_sll(buf, 0, 0, 0)
-#define i_ssnop(buf) i_sll(buf, 0, 0, 1)
-#define i_ehb(buf) i_sll(buf, 0, 0, 3)
-
-static int __init __maybe_unused in_compat_space_p(long addr)
-{
- /* Is this address in 32bit compat space? */
-#ifdef CONFIG_64BIT
- return (((addr) & 0xffffffff00000000L) == 0xffffffff00000000L);
-#else
- return 1;
+UASM_L_LA(_module_alloc)
#endif
-}
-
-static int __init __maybe_unused rel_highest(long val)
-{
-#ifdef CONFIG_64BIT
- return ((((val + 0x800080008000L) >> 48) & 0xffff) ^ 0x8000) - 0x8000;
-#else
- return 0;
-#endif
-}
-
-static int __init __maybe_unused rel_higher(long val)
-{
-#ifdef CONFIG_64BIT
- return ((((val + 0x80008000L) >> 32) & 0xffff) ^ 0x8000) - 0x8000;
-#else
- return 0;
-#endif
-}
-
-static int __init rel_hi(long val)
-{
- return ((((val + 0x8000L) >> 16) & 0xffff) ^ 0x8000) - 0x8000;
-}
-
-static int __init rel_lo(long val)
-{
- return ((val & 0xffff) ^ 0x8000) - 0x8000;
-}
-
-static void __init i_LA_mostly(u32 **buf, unsigned int rs, long addr)
-{
- if (!in_compat_space_p(addr)) {
- i_lui(buf, rs, rel_highest(addr));
- if (rel_higher(addr))
- i_daddiu(buf, rs, rs, rel_higher(addr));
- if (rel_hi(addr)) {
- i_dsll(buf, rs, rs, 16);
- i_daddiu(buf, rs, rs, rel_hi(addr));
- i_dsll(buf, rs, rs, 16);
- } else
- i_dsll32(buf, rs, rs, 0);
- } else
- i_lui(buf, rs, rel_hi(addr));
-}
-
-static void __init __maybe_unused i_LA(u32 **buf, unsigned int rs, long addr)
-{
- i_LA_mostly(buf, rs, addr);
- if (rel_lo(addr)) {
- if (!in_compat_space_p(addr))
- i_daddiu(buf, rs, rs, rel_lo(addr));
- else
- i_addiu(buf, rs, rs, rel_lo(addr));
- }
-}
-
-/*
- * handle relocations
- */
-
-struct reloc {
- u32 *addr;
- unsigned int type;
- enum label_id lab;
-};
-
-static void __init r_mips_pc16(struct reloc **rel, u32 *addr,
- enum label_id l)
-{
- (*rel)->addr = addr;
- (*rel)->type = R_MIPS_PC16;
- (*rel)->lab = l;
- (*rel)++;
-}
-
-static inline void __resolve_relocs(struct reloc *rel, struct label *lab)
-{
- long laddr = (long)lab->addr;
- long raddr = (long)rel->addr;
-
- switch (rel->type) {
- case R_MIPS_PC16:
- *rel->addr |= build_bimm(laddr - (raddr + 4));
- break;
-
- default:
- panic("Unsupported TLB synthesizer relocation %d",
- rel->type);
- }
-}
-
-static void __init resolve_relocs(struct reloc *rel, struct label *lab)
-{
- struct label *l;
-
- for (; rel->lab != label_invalid; rel++)
- for (l = lab; l->lab != label_invalid; l++)
- if (rel->lab == l->lab)
- __resolve_relocs(rel, l);
-}
-
-static void __init move_relocs(struct reloc *rel, u32 *first, u32 *end,
- long off)
-{
- for (; rel->lab != label_invalid; rel++)
- if (rel->addr >= first && rel->addr < end)
- rel->addr += off;
-}
-
-static void __init move_labels(struct label *lab, u32 *first, u32 *end,
- long off)
-{
- for (; lab->lab != label_invalid; lab++)
- if (lab->addr >= first && lab->addr < end)
- lab->addr += off;
-}
-
-static void __init copy_handler(struct reloc *rel, struct label *lab,
- u32 *first, u32 *end, u32 *target)
-{
- long off = (long)(target - first);
-
- memcpy(target, first, (end - first) * sizeof(u32));
-
- move_relocs(rel, first, end, off);
- move_labels(lab, first, end, off);
-}
-
-static int __init __maybe_unused insn_has_bdelay(struct reloc *rel,
- u32 *addr)
-{
- for (; rel->lab != label_invalid; rel++) {
- if (rel->addr == addr
- && (rel->type == R_MIPS_PC16
- || rel->type == R_MIPS_26))
- return 1;
- }
-
- return 0;
-}
-
-/* convenience functions for labeled branches */
-static void __init __maybe_unused
- il_bltz(u32 **p, struct reloc **r, unsigned int reg, enum label_id l)
-{
- r_mips_pc16(r, *p, l);
- i_bltz(p, reg, 0);
-}
-
-static void __init __maybe_unused il_b(u32 **p, struct reloc **r,
- enum label_id l)
-{
- r_mips_pc16(r, *p, l);
- i_b(p, 0);
-}
-
-static void __init il_beqz(u32 **p, struct reloc **r, unsigned int reg,
- enum label_id l)
-{
- r_mips_pc16(r, *p, l);
- i_beqz(p, reg, 0);
-}
-
-static void __init __maybe_unused
-il_beqzl(u32 **p, struct reloc **r, unsigned int reg, enum label_id l)
-{
- r_mips_pc16(r, *p, l);
- i_beqzl(p, reg, 0);
-}
-
-static void __init il_bnez(u32 **p, struct reloc **r, unsigned int reg,
- enum label_id l)
-{
- r_mips_pc16(r, *p, l);
- i_bnez(p, reg, 0);
-}
-
-static void __init il_bgezl(u32 **p, struct reloc **r, unsigned int reg,
- enum label_id l)
-{
- r_mips_pc16(r, *p, l);
- i_bgezl(p, reg, 0);
-}
-
-static void __init __maybe_unused
-il_bgez(u32 **p, struct reloc **r, unsigned int reg, enum label_id l)
-{
- r_mips_pc16(r, *p, l);
- i_bgez(p, reg, 0);
-}
+UASM_L_LA(_vmalloc)
+UASM_L_LA(_vmalloc_done)
+UASM_L_LA(_tlbw_hazard)
+UASM_L_LA(_split)
+UASM_L_LA(_nopage_tlbl)
+UASM_L_LA(_nopage_tlbs)
+UASM_L_LA(_nopage_tlbm)
+UASM_L_LA(_smp_pgtable_change)
+UASM_L_LA(_r3000_write_probe_fail)
/*
* For debug purposes.
@@ -752,9 +131,9 @@ static inline void dump_handler(const u32 *handler, int count)
#define C0_XCONTEXT 20, 0
#ifdef CONFIG_64BIT
-# define GET_CONTEXT(buf, reg) i_MFC0(buf, reg, C0_XCONTEXT)
+# define GET_CONTEXT(buf, reg) UASM_i_MFC0(buf, reg, C0_XCONTEXT)
#else
-# define GET_CONTEXT(buf, reg) i_MFC0(buf, reg, C0_CONTEXT)
+# define GET_CONTEXT(buf, reg) UASM_i_MFC0(buf, reg, C0_CONTEXT)
#endif
/* The worst case length of the handler is around 18 instructions for
@@ -768,8 +147,8 @@ static inline void dump_handler(const u32 *handler, int count)
static u32 tlb_handler[128] __initdata;
/* simply assume worst case size for labels and relocs */
-static struct label labels[128] __initdata;
-static struct reloc relocs[128] __initdata;
+static struct uasm_label labels[128] __initdata;
+static struct uasm_reloc relocs[128] __initdata;
/*
* The R3000 TLB handler is simple.
@@ -782,29 +161,29 @@ static void __init build_r3000_tlb_refill_handler(void)
memset(tlb_handler, 0, sizeof(tlb_handler));
p = tlb_handler;
- i_mfc0(&p, K0, C0_BADVADDR);
- i_lui(&p, K1, rel_hi(pgdc)); /* cp0 delay */
- i_lw(&p, K1, rel_lo(pgdc), K1);
- i_srl(&p, K0, K0, 22); /* load delay */
- i_sll(&p, K0, K0, 2);
- i_addu(&p, K1, K1, K0);
- i_mfc0(&p, K0, C0_CONTEXT);
- i_lw(&p, K1, 0, K1); /* cp0 delay */
- i_andi(&p, K0, K0, 0xffc); /* load delay */
- i_addu(&p, K1, K1, K0);
- i_lw(&p, K0, 0, K1);
- i_nop(&p); /* load delay */
- i_mtc0(&p, K0, C0_ENTRYLO0);
- i_mfc0(&p, K1, C0_EPC); /* cp0 delay */
- i_tlbwr(&p); /* cp0 delay */
- i_jr(&p, K1);
- i_rfe(&p); /* branch delay */
+ uasm_i_mfc0(&p, K0, C0_BADVADDR);
+ uasm_i_lui(&p, K1, uasm_rel_hi(pgdc)); /* cp0 delay */
+ uasm_i_lw(&p, K1, uasm_rel_lo(pgdc), K1);
+ uasm_i_srl(&p, K0, K0, 22); /* load delay */
+ uasm_i_sll(&p, K0, K0, 2);
+ uasm_i_addu(&p, K1, K1, K0);
+ uasm_i_mfc0(&p, K0, C0_CONTEXT);
+ uasm_i_lw(&p, K1, 0, K1); /* cp0 delay */
+ uasm_i_andi(&p, K0, K0, 0xffc); /* load delay */
+ uasm_i_addu(&p, K1, K1, K0);
+ uasm_i_lw(&p, K0, 0, K1);
+ uasm_i_nop(&p); /* load delay */
+ uasm_i_mtc0(&p, K0, C0_ENTRYLO0);
+ uasm_i_mfc0(&p, K1, C0_EPC); /* cp0 delay */
+ uasm_i_tlbwr(&p); /* cp0 delay */
+ uasm_i_jr(&p, K1);
+ uasm_i_rfe(&p); /* branch delay */
if (p > tlb_handler + 32)
panic("TLB refill handler space exceeded");
- pr_info("Synthesized TLB refill handler (%u instructions).\n",
- (unsigned int)(p - tlb_handler));
+ pr_debug("Wrote TLB refill handler (%u instructions).\n",
+ (unsigned int)(p - tlb_handler));
memcpy((void *)ebase, tlb_handler, 0x80);
@@ -850,12 +229,12 @@ static void __init __maybe_unused build_tlb_probe_entry(u32 **p)
case CPU_R5000:
case CPU_R5000A:
case CPU_NEVADA:
- i_nop(p);
- i_tlbp(p);
+ uasm_i_nop(p);
+ uasm_i_tlbp(p);
break;
default:
- i_tlbp(p);
+ uasm_i_tlbp(p);
break;
}
}
@@ -866,19 +245,19 @@ static void __init __maybe_unused build_tlb_probe_entry(u32 **p)
*/
enum tlb_write_entry { tlb_random, tlb_indexed };
-static void __init build_tlb_write_entry(u32 **p, struct label **l,
- struct reloc **r,
+static void __init build_tlb_write_entry(u32 **p, struct uasm_label **l,
+ struct uasm_reloc **r,
enum tlb_write_entry wmode)
{
void(*tlbw)(u32 **) = NULL;
switch (wmode) {
- case tlb_random: tlbw = i_tlbwr; break;
- case tlb_indexed: tlbw = i_tlbwi; break;
+ case tlb_random: tlbw = uasm_i_tlbwr; break;
+ case tlb_indexed: tlbw = uasm_i_tlbwi; break;
}
if (cpu_has_mips_r2) {
- i_ehb(p);
+ uasm_i_ehb(p);
tlbw(p);
return;
}
@@ -894,19 +273,19 @@ static void __init build_tlb_write_entry(u32 **p, struct label **l,
* This branch uses up a mtc0 hazard nop slot and saves
* two nops after the tlbw instruction.
*/
- il_bgezl(p, r, 0, label_tlbw_hazard);
+ uasm_il_bgezl(p, r, 0, label_tlbw_hazard);
tlbw(p);
- l_tlbw_hazard(l, *p);
- i_nop(p);
+ uasm_l_tlbw_hazard(l, *p);
+ uasm_i_nop(p);
break;
case CPU_R4600:
case CPU_R4700:
case CPU_R5000:
case CPU_R5000A:
- i_nop(p);
+ uasm_i_nop(p);
tlbw(p);
- i_nop(p);
+ uasm_i_nop(p);
break;
case CPU_R4300:
@@ -920,7 +299,7 @@ static void __init build_tlb_write_entry(u32 **p, struct label **l,
case CPU_AU1210:
case CPU_AU1250:
case CPU_PR4450:
- i_nop(p);
+ uasm_i_nop(p);
tlbw(p);
break;
@@ -937,26 +316,26 @@ static void __init build_tlb_write_entry(u32 **p, struct label **l,
case CPU_BCM4710:
case CPU_LOONGSON2:
if (m4kc_tlbp_war())
- i_nop(p);
+ uasm_i_nop(p);
tlbw(p);
break;
case CPU_NEVADA:
- i_nop(p); /* QED specifies 2 nops hazard */
+ uasm_i_nop(p); /* QED specifies 2 nops hazard */
/*
* This branch uses up a mtc0 hazard nop slot and saves
* a nop after the tlbw instruction.
*/
- il_bgezl(p, r, 0, label_tlbw_hazard);
+ uasm_il_bgezl(p, r, 0, label_tlbw_hazard);
tlbw(p);
- l_tlbw_hazard(l, *p);
+ uasm_l_tlbw_hazard(l, *p);
break;
case CPU_RM7000:
- i_nop(p);
- i_nop(p);
- i_nop(p);
- i_nop(p);
+ uasm_i_nop(p);
+ uasm_i_nop(p);
+ uasm_i_nop(p);
+ uasm_i_nop(p);
tlbw(p);
break;
@@ -967,15 +346,15 @@ static void __init build_tlb_write_entry(u32 **p, struct label **l,
* cpu cycles and use for data translations should not occur
* for 3 cpu cycles.
*/
- i_ssnop(p);
- i_ssnop(p);
- i_ssnop(p);
- i_ssnop(p);
+ uasm_i_ssnop(p);
+ uasm_i_ssnop(p);
+ uasm_i_ssnop(p);
+ uasm_i_ssnop(p);
tlbw(p);
- i_ssnop(p);
- i_ssnop(p);
- i_ssnop(p);
- i_ssnop(p);
+ uasm_i_ssnop(p);
+ uasm_i_ssnop(p);
+ uasm_i_ssnop(p);
+ uasm_i_ssnop(p);
break;
case CPU_VR4111:
@@ -983,18 +362,18 @@ static void __init build_tlb_write_entry(u32 **p, struct label **l,
case CPU_VR4122:
case CPU_VR4181:
case CPU_VR4181A:
- i_nop(p);
- i_nop(p);
+ uasm_i_nop(p);
+ uasm_i_nop(p);
tlbw(p);
- i_nop(p);
- i_nop(p);
+ uasm_i_nop(p);
+ uasm_i_nop(p);
break;
case CPU_VR4131:
case CPU_VR4133:
case CPU_R5432:
- i_nop(p);
- i_nop(p);
+ uasm_i_nop(p);
+ uasm_i_nop(p);
tlbw(p);
break;
@@ -1011,7 +390,7 @@ static void __init build_tlb_write_entry(u32 **p, struct label **l,
* TMP will be clobbered, PTR will hold the pmd entry.
*/
static void __init
-build_get_pmde64(u32 **p, struct label **l, struct reloc **r,
+build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
unsigned int tmp, unsigned int ptr)
{
long pgdc = (long)pgd_current;
@@ -1019,52 +398,52 @@ build_get_pmde64(u32 **p, struct label **l, struct reloc **r,
/*
* The vmalloc handling is not in the hotpath.
*/
- i_dmfc0(p, tmp, C0_BADVADDR);
+ uasm_i_dmfc0(p, tmp, C0_BADVADDR);
#ifdef MODULE_START
- il_bltz(p, r, tmp, label_module_alloc);
+ uasm_il_bltz(p, r, tmp, label_module_alloc);
#else
- il_bltz(p, r, tmp, label_vmalloc);
+ uasm_il_bltz(p, r, tmp, label_vmalloc);
#endif
- /* No i_nop needed here, since the next insn doesn't touch TMP. */
+ /* No uasm_i_nop needed here, since the next insn doesn't touch TMP. */
#ifdef CONFIG_SMP
# ifdef CONFIG_MIPS_MT_SMTC
/*
* SMTC uses TCBind value as "CPU" index
*/
- i_mfc0(p, ptr, C0_TCBIND);
- i_dsrl(p, ptr, ptr, 19);
+ uasm_i_mfc0(p, ptr, C0_TCBIND);
+ uasm_i_dsrl(p, ptr, ptr, 19);
# else
/*
* 64 bit SMP running in XKPHYS has smp_processor_id() << 3
* stored in CONTEXT.
*/
- i_dmfc0(p, ptr, C0_CONTEXT);
- i_dsrl(p, ptr, ptr, 23);
+ uasm_i_dmfc0(p, ptr, C0_CONTEXT);
+ uasm_i_dsrl(p, ptr, ptr, 23);
#endif
- i_LA_mostly(p, tmp, pgdc);
- i_daddu(p, ptr, ptr, tmp);
- i_dmfc0(p, tmp, C0_BADVADDR);
- i_ld(p, ptr, rel_lo(pgdc), ptr);
+ UASM_i_LA_mostly(p, tmp, pgdc);
+ uasm_i_daddu(p, ptr, ptr, tmp);
+ uasm_i_dmfc0(p, tmp, C0_BADVADDR);
+ uasm_i_ld(p, ptr, uasm_rel_lo(pgdc), ptr);
#else
- i_LA_mostly(p, ptr, pgdc);
- i_ld(p, ptr, rel_lo(pgdc), ptr);
+ UASM_i_LA_mostly(p, ptr, pgdc);
+ uasm_i_ld(p, ptr, uasm_rel_lo(pgdc), ptr);
#endif
- l_vmalloc_done(l, *p);
+ uasm_l_vmalloc_done(l, *p);
if (PGDIR_SHIFT - 3 < 32) /* get pgd offset in bytes */
- i_dsrl(p, tmp, tmp, PGDIR_SHIFT-3);
+ uasm_i_dsrl(p, tmp, tmp, PGDIR_SHIFT-3);
else
- i_dsrl32(p, tmp, tmp, PGDIR_SHIFT - 3 - 32);
-
- i_andi(p, tmp, tmp, (PTRS_PER_PGD - 1)<<3);
- i_daddu(p, ptr, ptr, tmp); /* add in pgd offset */
- i_dmfc0(p, tmp, C0_BADVADDR); /* get faulting address */
- i_ld(p, ptr, 0, ptr); /* get pmd pointer */
- i_dsrl(p, tmp, tmp, PMD_SHIFT-3); /* get pmd offset in bytes */
- i_andi(p, tmp, tmp, (PTRS_PER_PMD - 1)<<3);
- i_daddu(p, ptr, ptr, tmp); /* add in pmd offset */
+ uasm_i_dsrl32(p, tmp, tmp, PGDIR_SHIFT - 3 - 32);
+
+ uasm_i_andi(p, tmp, tmp, (PTRS_PER_PGD - 1)<<3);
+ uasm_i_daddu(p, ptr, ptr, tmp); /* add in pgd offset */
+ uasm_i_dmfc0(p, tmp, C0_BADVADDR); /* get faulting address */
+ uasm_i_ld(p, ptr, 0, ptr); /* get pmd pointer */
+ uasm_i_dsrl(p, tmp, tmp, PMD_SHIFT-3); /* get pmd offset in bytes */
+ uasm_i_andi(p, tmp, tmp, (PTRS_PER_PMD - 1)<<3);
+ uasm_i_daddu(p, ptr, ptr, tmp); /* add in pmd offset */
}
/*
@@ -1072,7 +451,7 @@ build_get_pmde64(u32 **p, struct label **l, struct reloc **r,
* PTR will hold the pgd for vmalloc.
*/
static void __init
-build_get_pgd_vmalloc64(u32 **p, struct label **l, struct reloc **r,
+build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
unsigned int bvaddr, unsigned int ptr)
{
long swpd = (long)swapper_pg_dir;
@@ -1080,58 +459,60 @@ build_get_pgd_vmalloc64(u32 **p, struct label **l, struct reloc **r,
#ifdef MODULE_START
long modd = (long)module_pg_dir;
- l_module_alloc(l, *p);
+ uasm_l_module_alloc(l, *p);
/*
* Assumption:
* VMALLOC_START >= 0xc000000000000000UL
* MODULE_START >= 0xe000000000000000UL
*/
- i_SLL(p, ptr, bvaddr, 2);
- il_bgez(p, r, ptr, label_vmalloc);
+ UASM_i_SLL(p, ptr, bvaddr, 2);
+ uasm_il_bgez(p, r, ptr, label_vmalloc);
- if (in_compat_space_p(MODULE_START) && !rel_lo(MODULE_START)) {
- i_lui(p, ptr, rel_hi(MODULE_START)); /* delay slot */
+ if (uasm_in_compat_space_p(MODULE_START) &&
+ !uasm_rel_lo(MODULE_START)) {
+ uasm_i_lui(p, ptr, uasm_rel_hi(MODULE_START)); /* delay slot */
} else {
/* unlikely configuration */
- i_nop(p); /* delay slot */
- i_LA(p, ptr, MODULE_START);
+ uasm_i_nop(p); /* delay slot */
+ UASM_i_LA(p, ptr, MODULE_START);
}
- i_dsubu(p, bvaddr, bvaddr, ptr);
+ uasm_i_dsubu(p, bvaddr, bvaddr, ptr);
- if (in_compat_space_p(modd) && !rel_lo(modd)) {
- il_b(p, r, label_vmalloc_done);
- i_lui(p, ptr, rel_hi(modd));
+ if (uasm_in_compat_space_p(modd) && !uasm_rel_lo(modd)) {
+ uasm_il_b(p, r, label_vmalloc_done);
+ uasm_i_lui(p, ptr, uasm_rel_hi(modd));
} else {
- i_LA_mostly(p, ptr, modd);
- il_b(p, r, label_vmalloc_done);
- if (in_compat_space_p(modd))
- i_addiu(p, ptr, ptr, rel_lo(modd));
+ UASM_i_LA_mostly(p, ptr, modd);
+ uasm_il_b(p, r, label_vmalloc_done);
+ if (uasm_in_compat_space_p(modd))
+ uasm_i_addiu(p, ptr, ptr, uasm_rel_lo(modd));
else
- i_daddiu(p, ptr, ptr, rel_lo(modd));
+ uasm_i_daddiu(p, ptr, ptr, uasm_rel_lo(modd));
}
- l_vmalloc(l, *p);
- if (in_compat_space_p(MODULE_START) && !rel_lo(MODULE_START) &&
+ uasm_l_vmalloc(l, *p);
+ if (uasm_in_compat_space_p(MODULE_START) &&
+ !uasm_rel_lo(MODULE_START) &&
MODULE_START << 32 == VMALLOC_START)
- i_dsll32(p, ptr, ptr, 0); /* typical case */
+ uasm_i_dsll32(p, ptr, ptr, 0); /* typical case */
else
- i_LA(p, ptr, VMALLOC_START);
+ UASM_i_LA(p, ptr, VMALLOC_START);
#else
- l_vmalloc(l, *p);
- i_LA(p, ptr, VMALLOC_START);
+ uasm_l_vmalloc(l, *p);
+ UASM_i_LA(p, ptr, VMALLOC_START);
#endif
- i_dsubu(p, bvaddr, bvaddr, ptr);
+ uasm_i_dsubu(p, bvaddr, bvaddr, ptr);
- if (in_compat_space_p(swpd) && !rel_lo(swpd)) {
- il_b(p, r, label_vmalloc_done);
- i_lui(p, ptr, rel_hi(swpd));
+ if (uasm_in_compat_space_p(swpd) && !uasm_rel_lo(swpd)) {
+ uasm_il_b(p, r, label_vmalloc_done);
+ uasm_i_lui(p, ptr, uasm_rel_hi(swpd));
} else {
- i_LA_mostly(p, ptr, swpd);
- il_b(p, r, label_vmalloc_done);
- if (in_compat_space_p(swpd))
- i_addiu(p, ptr, ptr, rel_lo(swpd));
+ UASM_i_LA_mostly(p, ptr, swpd);
+ uasm_il_b(p, r, label_vmalloc_done);
+ if (uasm_in_compat_space_p(swpd))
+ uasm_i_addiu(p, ptr, ptr, uasm_rel_lo(swpd));
else
- i_daddiu(p, ptr, ptr, rel_lo(swpd));
+ uasm_i_daddiu(p, ptr, ptr, uasm_rel_lo(swpd));
}
}
@@ -1152,26 +533,26 @@ build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr)
/*
* SMTC uses TCBind value as "CPU" index
*/
- i_mfc0(p, ptr, C0_TCBIND);
- i_LA_mostly(p, tmp, pgdc);
- i_srl(p, ptr, ptr, 19);
+ uasm_i_mfc0(p, ptr, C0_TCBIND);
+ UASM_i_LA_mostly(p, tmp, pgdc);
+ uasm_i_srl(p, ptr, ptr, 19);
#else
/*
* smp_processor_id() << 3 is stored in CONTEXT.
*/
- i_mfc0(p, ptr, C0_CONTEXT);
- i_LA_mostly(p, tmp, pgdc);
- i_srl(p, ptr, ptr, 23);
+ uasm_i_mfc0(p, ptr, C0_CONTEXT);
+ UASM_i_LA_mostly(p, tmp, pgdc);
+ uasm_i_srl(p, ptr, ptr, 23);
#endif
- i_addu(p, ptr, tmp, ptr);
+ uasm_i_addu(p, ptr, tmp, ptr);
#else
- i_LA_mostly(p, ptr, pgdc);
+ UASM_i_LA_mostly(p, ptr, pgdc);
#endif
- i_mfc0(p, tmp, C0_BADVADDR); /* get faulting address */
- i_lw(p, ptr, rel_lo(pgdc), ptr);
- i_srl(p, tmp, tmp, PGDIR_SHIFT); /* get pgd only bits */
- i_sll(p, tmp, tmp, PGD_T_LOG2);
- i_addu(p, ptr, ptr, tmp); /* add in pgd offset */
+ uasm_i_mfc0(p, tmp, C0_BADVADDR); /* get faulting address */
+ uasm_i_lw(p, ptr, uasm_rel_lo(pgdc), ptr);
+ uasm_i_srl(p, tmp, tmp, PGDIR_SHIFT); /* get pgd only bits */
+ uasm_i_sll(p, tmp, tmp, PGD_T_LOG2);
+ uasm_i_addu(p, ptr, ptr, tmp); /* add in pgd offset */
}
#endif /* !CONFIG_64BIT */
@@ -1198,8 +579,8 @@ static void __init build_adjust_context(u32 **p, unsigned int ctx)
}
if (shift)
- i_SRL(p, ctx, ctx, shift);
- i_andi(p, ctx, ctx, mask);
+ UASM_i_SRL(p, ctx, ctx, shift);
+ uasm_i_andi(p, ctx, ctx, mask);
}
static void __init build_get_ptep(u32 **p, unsigned int tmp, unsigned int ptr)
@@ -1213,18 +594,18 @@ static void __init build_get_ptep(u32 **p, unsigned int tmp, unsigned int ptr)
*/
switch (current_cpu_type()) {
case CPU_NEVADA:
- i_LW(p, ptr, 0, ptr);
+ UASM_i_LW(p, ptr, 0, ptr);
GET_CONTEXT(p, tmp); /* get context reg */
break;
default:
GET_CONTEXT(p, tmp); /* get context reg */
- i_LW(p, ptr, 0, ptr);
+ UASM_i_LW(p, ptr, 0, ptr);
break;
}
build_adjust_context(p, tmp);
- i_ADDU(p, ptr, ptr, tmp); /* add in offset */
+ UASM_i_ADDU(p, ptr, ptr, tmp); /* add in offset */
}
static void __init build_update_entries(u32 **p, unsigned int tmp,
@@ -1236,45 +617,45 @@ static void __init build_update_entries(u32 **p, unsigned int tmp,
*/
#ifdef CONFIG_64BIT_PHYS_ADDR
if (cpu_has_64bits) {
- i_ld(p, tmp, 0, ptep); /* get even pte */
- i_ld(p, ptep, sizeof(pte_t), ptep); /* get odd pte */
- i_dsrl(p, tmp, tmp, 6); /* convert to entrylo0 */
- i_mtc0(p, tmp, C0_ENTRYLO0); /* load it */
- i_dsrl(p, ptep, ptep, 6); /* convert to entrylo1 */
- i_mtc0(p, ptep, C0_ENTRYLO1); /* load it */
+ uasm_i_ld(p, tmp, 0, ptep); /* get even pte */
+ uasm_i_ld(p, ptep, sizeof(pte_t), ptep); /* get odd pte */
+ uasm_i_dsrl(p, tmp, tmp, 6); /* convert to entrylo0 */
+ uasm_i_mtc0(p, tmp, C0_ENTRYLO0); /* load it */
+ uasm_i_dsrl(p, ptep, ptep, 6); /* convert to entrylo1 */
+ uasm_i_mtc0(p, ptep, C0_ENTRYLO1); /* load it */
} else {
int pte_off_even = sizeof(pte_t) / 2;
int pte_off_odd = pte_off_even + sizeof(pte_t);
/* The pte entries are pre-shifted */
- i_lw(p, tmp, pte_off_even, ptep); /* get even pte */
- i_mtc0(p, tmp, C0_ENTRYLO0); /* load it */
- i_lw(p, ptep, pte_off_odd, ptep); /* get odd pte */
- i_mtc0(p, ptep, C0_ENTRYLO1); /* load it */
+ uasm_i_lw(p, tmp, pte_off_even, ptep); /* get even pte */
+ uasm_i_mtc0(p, tmp, C0_ENTRYLO0); /* load it */
+ uasm_i_lw(p, ptep, pte_off_odd, ptep); /* get odd pte */
+ uasm_i_mtc0(p, ptep, C0_ENTRYLO1); /* load it */
}
#else
- i_LW(p, tmp, 0, ptep); /* get even pte */
- i_LW(p, ptep, sizeof(pte_t), ptep); /* get odd pte */
+ UASM_i_LW(p, tmp, 0, ptep); /* get even pte */
+ UASM_i_LW(p, ptep, sizeof(pte_t), ptep); /* get odd pte */
if (r45k_bvahwbug())
build_tlb_probe_entry(p);
- i_SRL(p, tmp, tmp, 6); /* convert to entrylo0 */
+ UASM_i_SRL(p, tmp, tmp, 6); /* convert to entrylo0 */
if (r4k_250MHZhwbug())
- i_mtc0(p, 0, C0_ENTRYLO0);
- i_mtc0(p, tmp, C0_ENTRYLO0); /* load it */
- i_SRL(p, ptep, ptep, 6); /* convert to entrylo1 */
+ uasm_i_mtc0(p, 0, C0_ENTRYLO0);
+ uasm_i_mtc0(p, tmp, C0_ENTRYLO0); /* load it */
+ UASM_i_SRL(p, ptep, ptep, 6); /* convert to entrylo1 */
if (r45k_bvahwbug())
- i_mfc0(p, tmp, C0_INDEX);
+ uasm_i_mfc0(p, tmp, C0_INDEX);
if (r4k_250MHZhwbug())
- i_mtc0(p, 0, C0_ENTRYLO1);
- i_mtc0(p, ptep, C0_ENTRYLO1); /* load it */
+ uasm_i_mtc0(p, 0, C0_ENTRYLO1);
+ uasm_i_mtc0(p, ptep, C0_ENTRYLO1); /* load it */
#endif
}
static void __init build_r4000_tlb_refill_handler(void)
{
u32 *p = tlb_handler;
- struct label *l = labels;
- struct reloc *r = relocs;
+ struct uasm_label *l = labels;
+ struct uasm_reloc *r = relocs;
u32 *f;
unsigned int final_len;
@@ -1287,12 +668,12 @@ static void __init build_r4000_tlb_refill_handler(void)
* create the plain linear handler
*/
if (bcm1250_m3_war()) {
- i_MFC0(&p, K0, C0_BADVADDR);
- i_MFC0(&p, K1, C0_ENTRYHI);
- i_xor(&p, K0, K0, K1);
- i_SRL(&p, K0, K0, PAGE_SHIFT + 1);
- il_bnez(&p, &r, K0, label_leave);
- /* No need for i_nop */
+ UASM_i_MFC0(&p, K0, C0_BADVADDR);
+ UASM_i_MFC0(&p, K1, C0_ENTRYHI);
+ uasm_i_xor(&p, K0, K0, K1);
+ UASM_i_SRL(&p, K0, K0, PAGE_SHIFT + 1);
+ uasm_il_bnez(&p, &r, K0, label_leave);
+ /* No need for uasm_i_nop */
}
#ifdef CONFIG_64BIT
@@ -1304,8 +685,8 @@ static void __init build_r4000_tlb_refill_handler(void)
build_get_ptep(&p, K0, K1);
build_update_entries(&p, K0, K1);
build_tlb_write_entry(&p, &l, &r, tlb_random);
- l_leave(&l, p);
- i_eret(&p); /* return from trap */
+ uasm_l_leave(&l, p);
+ uasm_i_eret(&p); /* return from trap */
#ifdef CONFIG_64BIT
build_get_pgd_vmalloc64(&p, &l, &r, K0, K1);
@@ -1325,7 +706,7 @@ static void __init build_r4000_tlb_refill_handler(void)
#else
if (((p - tlb_handler) > 63)
|| (((p - tlb_handler) > 61)
- && insn_has_bdelay(relocs, tlb_handler + 29)))
+ && uasm_insn_has_bdelay(relocs, tlb_handler + 29)))
panic("TLB refill handler space exceeded");
#endif
@@ -1335,13 +716,13 @@ static void __init build_r4000_tlb_refill_handler(void)
#if defined(CONFIG_32BIT) || defined(CONFIG_CPU_LOONGSON2)
f = final_handler;
/* Simplest case, just copy the handler. */
- copy_handler(relocs, labels, tlb_handler, p, f);
+ uasm_copy_handler(relocs, labels, tlb_handler, p, f);
final_len = p - tlb_handler;
#else /* CONFIG_64BIT */
f = final_handler + 32;
if ((p - tlb_handler) <= 32) {
/* Just copy the handler. */
- copy_handler(relocs, labels, tlb_handler, p, f);
+ uasm_copy_handler(relocs, labels, tlb_handler, p, f);
final_len = p - tlb_handler;
} else {
u32 *split = tlb_handler + 30;
@@ -1349,34 +730,34 @@ static void __init build_r4000_tlb_refill_handler(void)
/*
* Find the split point.
*/
- if (insn_has_bdelay(relocs, split - 1))
+ if (uasm_insn_has_bdelay(relocs, split - 1))
split--;
/* Copy first part of the handler. */
- copy_handler(relocs, labels, tlb_handler, split, f);
+ uasm_copy_handler(relocs, labels, tlb_handler, split, f);
f += split - tlb_handler;
/* Insert branch. */
- l_split(&l, final_handler);
- il_b(&f, &r, label_split);
- if (insn_has_bdelay(relocs, split))
- i_nop(&f);
+ uasm_l_split(&l, final_handler);
+ uasm_il_b(&f, &r, label_split);
+ if (uasm_insn_has_bdelay(relocs, split))
+ uasm_i_nop(&f);
else {
- copy_handler(relocs, labels, split, split + 1, f);
- move_labels(labels, f, f + 1, -1);
+ uasm_copy_handler(relocs, labels, split, split + 1, f);
+ uasm_move_labels(labels, f, f + 1, -1);
f++;
split++;
}
/* Copy the rest of the handler. */
- copy_handler(relocs, labels, split, p, final_handler);
+ uasm_copy_handler(relocs, labels, split, p, final_handler);
final_len = (f - (final_handler + 32)) + (p - split);
}
#endif /* CONFIG_64BIT */
- resolve_relocs(relocs, labels);
- pr_info("Synthesized TLB refill handler (%u instructions).\n",
- final_len);
+ uasm_resolve_relocs(relocs, labels);
+ pr_debug("Wrote TLB refill handler (%u instructions).\n",
+ final_len);
memcpy((void *)ebase, final_handler, 0x100);
@@ -1403,75 +784,75 @@ u32 handle_tlbs[FASTPATH_SIZE] __cacheline_aligned;
u32 handle_tlbm[FASTPATH_SIZE] __cacheline_aligned;
static void __init
-iPTE_LW(u32 **p, struct label **l, unsigned int pte, unsigned int ptr)
+iPTE_LW(u32 **p, struct uasm_label **l, unsigned int pte, unsigned int ptr)
{
#ifdef CONFIG_SMP
# ifdef CONFIG_64BIT_PHYS_ADDR
if (cpu_has_64bits)
- i_lld(p, pte, 0, ptr);
+ uasm_i_lld(p, pte, 0, ptr);
else
# endif
- i_LL(p, pte, 0, ptr);
+ UASM_i_LL(p, pte, 0, ptr);
#else
# ifdef CONFIG_64BIT_PHYS_ADDR
if (cpu_has_64bits)
- i_ld(p, pte, 0, ptr);
+ uasm_i_ld(p, pte, 0, ptr);
else
# endif
- i_LW(p, pte, 0, ptr);
+ UASM_i_LW(p, pte, 0, ptr);
#endif
}
static void __init
-iPTE_SW(u32 **p, struct reloc **r, unsigned int pte, unsigned int ptr,
+iPTE_SW(u32 **p, struct uasm_reloc **r, unsigned int pte, unsigned int ptr,
unsigned int mode)
{
#ifdef CONFIG_64BIT_PHYS_ADDR
unsigned int hwmode = mode & (_PAGE_VALID | _PAGE_DIRTY);
#endif
- i_ori(p, pte, pte, mode);
+ uasm_i_ori(p, pte, pte, mode);
#ifdef CONFIG_SMP
# ifdef CONFIG_64BIT_PHYS_ADDR
if (cpu_has_64bits)
- i_scd(p, pte, 0, ptr);
+ uasm_i_scd(p, pte, 0, ptr);
else
# endif
- i_SC(p, pte, 0, ptr);
+ UASM_i_SC(p, pte, 0, ptr);
if (r10000_llsc_war())
- il_beqzl(p, r, pte, label_smp_pgtable_change);
+ uasm_il_beqzl(p, r, pte, label_smp_pgtable_change);
else
- il_beqz(p, r, pte, label_smp_pgtable_change);
+ uasm_il_beqz(p, r, pte, label_smp_pgtable_change);
# ifdef CONFIG_64BIT_PHYS_ADDR
if (!cpu_has_64bits) {
- /* no i_nop needed */
- i_ll(p, pte, sizeof(pte_t) / 2, ptr);
- i_ori(p, pte, pte, hwmode);
- i_sc(p, pte, sizeof(pte_t) / 2, ptr);
- il_beqz(p, r, pte, label_smp_pgtable_change);
- /* no i_nop needed */
- i_lw(p, pte, 0, ptr);
+ /* no uasm_i_nop needed */
+ uasm_i_ll(p, pte, sizeof(pte_t) / 2, ptr);
+ uasm_i_ori(p, pte, pte, hwmode);
+ uasm_i_sc(p, pte, sizeof(pte_t) / 2, ptr);
+ uasm_il_beqz(p, r, pte, label_smp_pgtable_change);
+ /* no uasm_i_nop needed */
+ uasm_i_lw(p, pte, 0, ptr);
} else
- i_nop(p);
+ uasm_i_nop(p);
# else
- i_nop(p);
+ uasm_i_nop(p);
# endif
#else
# ifdef CONFIG_64BIT_PHYS_ADDR
if (cpu_has_64bits)
- i_sd(p, pte, 0, ptr);
+ uasm_i_sd(p, pte, 0, ptr);
else
# endif
- i_SW(p, pte, 0, ptr);
+ UASM_i_SW(p, pte, 0, ptr);
# ifdef CONFIG_64BIT_PHYS_ADDR
if (!cpu_has_64bits) {
- i_lw(p, pte, sizeof(pte_t) / 2, ptr);
- i_ori(p, pte, pte, hwmode);
- i_sw(p, pte, sizeof(pte_t) / 2, ptr);
- i_lw(p, pte, 0, ptr);
+ uasm_i_lw(p, pte, sizeof(pte_t) / 2, ptr);
+ uasm_i_ori(p, pte, pte, hwmode);
+ uasm_i_sw(p, pte, sizeof(pte_t) / 2, ptr);
+ uasm_i_lw(p, pte, 0, ptr);
}
# endif
#endif
@@ -1483,18 +864,18 @@ iPTE_SW(u32 **p, struct reloc **r, unsigned int pte, unsigned int ptr,
* with it's original value.
*/
static void __init
-build_pte_present(u32 **p, struct label **l, struct reloc **r,
+build_pte_present(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
unsigned int pte, unsigned int ptr, enum label_id lid)
{
- i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_READ);
- i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_READ);
- il_bnez(p, r, pte, lid);
+ uasm_i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_READ);
+ uasm_i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_READ);
+ uasm_il_bnez(p, r, pte, lid);
iPTE_LW(p, l, pte, ptr);
}
/* Make PTE valid, store result in PTR. */
static void __init
-build_make_valid(u32 **p, struct reloc **r, unsigned int pte,
+build_make_valid(u32 **p, struct uasm_reloc **r, unsigned int pte,
unsigned int ptr)
{
unsigned int mode = _PAGE_VALID | _PAGE_ACCESSED;
@@ -1507,12 +888,12 @@ build_make_valid(u32 **p, struct reloc **r, unsigned int pte,
* restore PTE with value from PTR when done.
*/
static void __init
-build_pte_writable(u32 **p, struct label **l, struct reloc **r,
+build_pte_writable(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
unsigned int pte, unsigned int ptr, enum label_id lid)
{
- i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE);
- i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE);
- il_bnez(p, r, pte, lid);
+ uasm_i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE);
+ uasm_i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE);
+ uasm_il_bnez(p, r, pte, lid);
iPTE_LW(p, l, pte, ptr);
}
@@ -1520,7 +901,7 @@ build_pte_writable(u32 **p, struct label **l, struct reloc **r,
* at PTR.
*/
static void __init
-build_make_write(u32 **p, struct reloc **r, unsigned int pte,
+build_make_write(u32 **p, struct uasm_reloc **r, unsigned int pte,
unsigned int ptr)
{
unsigned int mode = (_PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_VALID
@@ -1534,11 +915,11 @@ build_make_write(u32 **p, struct reloc **r, unsigned int pte,
* restore PTE with value from PTR when done.
*/
static void __init
-build_pte_modifiable(u32 **p, struct label **l, struct reloc **r,
+build_pte_modifiable(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
unsigned int pte, unsigned int ptr, enum label_id lid)
{
- i_andi(p, pte, pte, _PAGE_WRITE);
- il_beqz(p, r, pte, lid);
+ uasm_i_andi(p, pte, pte, _PAGE_WRITE);
+ uasm_il_beqz(p, r, pte, lid);
iPTE_LW(p, l, pte, ptr);
}
@@ -1553,11 +934,11 @@ build_pte_modifiable(u32 **p, struct label **l, struct reloc **r,
static void __init
build_r3000_pte_reload_tlbwi(u32 **p, unsigned int pte, unsigned int tmp)
{
- i_mtc0(p, pte, C0_ENTRYLO0); /* cp0 delay */
- i_mfc0(p, tmp, C0_EPC); /* cp0 delay */
- i_tlbwi(p);
- i_jr(p, tmp);
- i_rfe(p); /* branch delay */
+ uasm_i_mtc0(p, pte, C0_ENTRYLO0); /* cp0 delay */
+ uasm_i_mfc0(p, tmp, C0_EPC); /* cp0 delay */
+ uasm_i_tlbwi(p);
+ uasm_i_jr(p, tmp);
+ uasm_i_rfe(p); /* branch delay */
}
/*
@@ -1567,20 +948,21 @@ build_r3000_pte_reload_tlbwi(u32 **p, unsigned int pte, unsigned int tmp)
* kseg2 access, i.e. without refill. Then it returns.
*/
static void __init
-build_r3000_tlb_reload_write(u32 **p, struct label **l, struct reloc **r,
- unsigned int pte, unsigned int tmp)
-{
- i_mfc0(p, tmp, C0_INDEX);
- i_mtc0(p, pte, C0_ENTRYLO0); /* cp0 delay */
- il_bltz(p, r, tmp, label_r3000_write_probe_fail); /* cp0 delay */
- i_mfc0(p, tmp, C0_EPC); /* branch delay */
- i_tlbwi(p); /* cp0 delay */
- i_jr(p, tmp);
- i_rfe(p); /* branch delay */
- l_r3000_write_probe_fail(l, *p);
- i_tlbwr(p); /* cp0 delay */
- i_jr(p, tmp);
- i_rfe(p); /* branch delay */
+build_r3000_tlb_reload_write(u32 **p, struct uasm_label **l,
+ struct uasm_reloc **r, unsigned int pte,
+ unsigned int tmp)
+{
+ uasm_i_mfc0(p, tmp, C0_INDEX);
+ uasm_i_mtc0(p, pte, C0_ENTRYLO0); /* cp0 delay */
+ uasm_il_bltz(p, r, tmp, label_r3000_write_probe_fail); /* cp0 delay */
+ uasm_i_mfc0(p, tmp, C0_EPC); /* branch delay */
+ uasm_i_tlbwi(p); /* cp0 delay */
+ uasm_i_jr(p, tmp);
+ uasm_i_rfe(p); /* branch delay */
+ uasm_l_r3000_write_probe_fail(l, *p);
+ uasm_i_tlbwr(p); /* cp0 delay */
+ uasm_i_jr(p, tmp);
+ uasm_i_rfe(p); /* branch delay */
}
static void __init
@@ -1589,25 +971,25 @@ build_r3000_tlbchange_handler_head(u32 **p, unsigned int pte,
{
long pgdc = (long)pgd_current;
- i_mfc0(p, pte, C0_BADVADDR);
- i_lui(p, ptr, rel_hi(pgdc)); /* cp0 delay */
- i_lw(p, ptr, rel_lo(pgdc), ptr);
- i_srl(p, pte, pte, 22); /* load delay */
- i_sll(p, pte, pte, 2);
- i_addu(p, ptr, ptr, pte);
- i_mfc0(p, pte, C0_CONTEXT);
- i_lw(p, ptr, 0, ptr); /* cp0 delay */
- i_andi(p, pte, pte, 0xffc); /* load delay */
- i_addu(p, ptr, ptr, pte);
- i_lw(p, pte, 0, ptr);
- i_tlbp(p); /* load delay */
+ uasm_i_mfc0(p, pte, C0_BADVADDR);
+ uasm_i_lui(p, ptr, uasm_rel_hi(pgdc)); /* cp0 delay */
+ uasm_i_lw(p, ptr, uasm_rel_lo(pgdc), ptr);
+ uasm_i_srl(p, pte, pte, 22); /* load delay */
+ uasm_i_sll(p, pte, pte, 2);
+ uasm_i_addu(p, ptr, ptr, pte);
+ uasm_i_mfc0(p, pte, C0_CONTEXT);
+ uasm_i_lw(p, ptr, 0, ptr); /* cp0 delay */
+ uasm_i_andi(p, pte, pte, 0xffc); /* load delay */
+ uasm_i_addu(p, ptr, ptr, pte);
+ uasm_i_lw(p, pte, 0, ptr);
+ uasm_i_tlbp(p); /* load delay */
}
static void __init build_r3000_tlb_load_handler(void)
{
u32 *p = handle_tlbl;
- struct label *l = labels;
- struct reloc *r = relocs;
+ struct uasm_label *l = labels;
+ struct uasm_reloc *r = relocs;
memset(handle_tlbl, 0, sizeof(handle_tlbl));
memset(labels, 0, sizeof(labels));
@@ -1615,20 +997,20 @@ static void __init build_r3000_tlb_load_handler(void)
build_r3000_tlbchange_handler_head(&p, K0, K1);
build_pte_present(&p, &l, &r, K0, K1, label_nopage_tlbl);
- i_nop(&p); /* load delay */
+ uasm_i_nop(&p); /* load delay */
build_make_valid(&p, &r, K0, K1);
build_r3000_tlb_reload_write(&p, &l, &r, K0, K1);
- l_nopage_tlbl(&l, p);
- i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff);
- i_nop(&p);
+ uasm_l_nopage_tlbl(&l, p);
+ uasm_i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff);
+ uasm_i_nop(&p);
if ((p - handle_tlbl) > FASTPATH_SIZE)
panic("TLB load handler fastpath space exceeded");
- resolve_relocs(relocs, labels);
- pr_info("Synthesized TLB load handler fastpath (%u instructions).\n",
- (unsigned int)(p - handle_tlbl));
+ uasm_resolve_relocs(relocs, labels);
+ pr_debug("Wrote TLB load handler fastpath (%u instructions).\n",
+ (unsigned int)(p - handle_tlbl));
dump_handler(handle_tlbl, ARRAY_SIZE(handle_tlbl));
}
@@ -1636,8 +1018,8 @@ static void __init build_r3000_tlb_load_handler(void)
static void __init build_r3000_tlb_store_handler(void)
{
u32 *p = handle_tlbs;
- struct label *l = labels;
- struct reloc *r = relocs;
+ struct uasm_label *l = labels;
+ struct uasm_reloc *r = relocs;
memset(handle_tlbs, 0, sizeof(handle_tlbs));
memset(labels, 0, sizeof(labels));
@@ -1645,20 +1027,20 @@ static void __init build_r3000_tlb_store_handler(void)
build_r3000_tlbchange_handler_head(&p, K0, K1);
build_pte_writable(&p, &l, &r, K0, K1, label_nopage_tlbs);
- i_nop(&p); /* load delay */
+ uasm_i_nop(&p); /* load delay */
build_make_write(&p, &r, K0, K1);
build_r3000_tlb_reload_write(&p, &l, &r, K0, K1);
- l_nopage_tlbs(&l, p);
- i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
- i_nop(&p);
+ uasm_l_nopage_tlbs(&l, p);
+ uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
+ uasm_i_nop(&p);
if ((p - handle_tlbs) > FASTPATH_SIZE)
panic("TLB store handler fastpath space exceeded");
- resolve_relocs(relocs, labels);
- pr_info("Synthesized TLB store handler fastpath (%u instructions).\n",
- (unsigned int)(p - handle_tlbs));
+ uasm_resolve_relocs(relocs, labels);
+ pr_debug("Wrote TLB store handler fastpath (%u instructions).\n",
+ (unsigned int)(p - handle_tlbs));
dump_handler(handle_tlbs, ARRAY_SIZE(handle_tlbs));
}
@@ -1666,8 +1048,8 @@ static void __init build_r3000_tlb_store_handler(void)
static void __init build_r3000_tlb_modify_handler(void)
{
u32 *p = handle_tlbm;
- struct label *l = labels;
- struct reloc *r = relocs;
+ struct uasm_label *l = labels;
+ struct uasm_reloc *r = relocs;
memset(handle_tlbm, 0, sizeof(handle_tlbm));
memset(labels, 0, sizeof(labels));
@@ -1675,20 +1057,20 @@ static void __init build_r3000_tlb_modify_handler(void)
build_r3000_tlbchange_handler_head(&p, K0, K1);
build_pte_modifiable(&p, &l, &r, K0, K1, label_nopage_tlbm);
- i_nop(&p); /* load delay */
+ uasm_i_nop(&p); /* load delay */
build_make_write(&p, &r, K0, K1);
build_r3000_pte_reload_tlbwi(&p, K0, K1);
- l_nopage_tlbm(&l, p);
- i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
- i_nop(&p);
+ uasm_l_nopage_tlbm(&l, p);
+ uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
+ uasm_i_nop(&p);
if ((p - handle_tlbm) > FASTPATH_SIZE)
panic("TLB modify handler fastpath space exceeded");
- resolve_relocs(relocs, labels);
- pr_info("Synthesized TLB modify handler fastpath (%u instructions).\n",
- (unsigned int)(p - handle_tlbm));
+ uasm_resolve_relocs(relocs, labels);
+ pr_debug("Wrote TLB modify handler fastpath (%u instructions).\n",
+ (unsigned int)(p - handle_tlbm));
dump_handler(handle_tlbm, ARRAY_SIZE(handle_tlbm));
}
@@ -1697,8 +1079,8 @@ static void __init build_r3000_tlb_modify_handler(void)
* R4000 style TLB load/store/modify handlers.
*/
static void __init
-build_r4000_tlbchange_handler_head(u32 **p, struct label **l,
- struct reloc **r, unsigned int pte,
+build_r4000_tlbchange_handler_head(u32 **p, struct uasm_label **l,
+ struct uasm_reloc **r, unsigned int pte,
unsigned int ptr)
{
#ifdef CONFIG_64BIT
@@ -1707,31 +1089,31 @@ build_r4000_tlbchange_handler_head(u32 **p, struct label **l,
build_get_pgde32(p, pte, ptr); /* get pgd in ptr */
#endif
- i_MFC0(p, pte, C0_BADVADDR);
- i_LW(p, ptr, 0, ptr);
- i_SRL(p, pte, pte, PAGE_SHIFT + PTE_ORDER - PTE_T_LOG2);
- i_andi(p, pte, pte, (PTRS_PER_PTE - 1) << PTE_T_LOG2);
- i_ADDU(p, ptr, ptr, pte);
+ UASM_i_MFC0(p, pte, C0_BADVADDR);
+ UASM_i_LW(p, ptr, 0, ptr);
+ UASM_i_SRL(p, pte, pte, PAGE_SHIFT + PTE_ORDER - PTE_T_LOG2);
+ uasm_i_andi(p, pte, pte, (PTRS_PER_PTE - 1) << PTE_T_LOG2);
+ UASM_i_ADDU(p, ptr, ptr, pte);
#ifdef CONFIG_SMP
- l_smp_pgtable_change(l, *p);
-# endif
+ uasm_l_smp_pgtable_change(l, *p);
+#endif
iPTE_LW(p, l, pte, ptr); /* get even pte */
if (!m4kc_tlbp_war())
build_tlb_probe_entry(p);
}
static void __init
-build_r4000_tlbchange_handler_tail(u32 **p, struct label **l,
- struct reloc **r, unsigned int tmp,
+build_r4000_tlbchange_handler_tail(u32 **p, struct uasm_label **l,
+ struct uasm_reloc **r, unsigned int tmp,
unsigned int ptr)
{
- i_ori(p, ptr, ptr, sizeof(pte_t));
- i_xori(p, ptr, ptr, sizeof(pte_t));
+ uasm_i_ori(p, ptr, ptr, sizeof(pte_t));
+ uasm_i_xori(p, ptr, ptr, sizeof(pte_t));
build_update_entries(p, tmp, ptr);
build_tlb_write_entry(p, l, r, tlb_indexed);
- l_leave(l, *p);
- i_eret(p); /* return from trap */
+ uasm_l_leave(l, *p);
+ uasm_i_eret(p); /* return from trap */
#ifdef CONFIG_64BIT
build_get_pgd_vmalloc64(p, l, r, tmp, ptr);
@@ -1741,20 +1123,20 @@ build_r4000_tlbchange_handler_tail(u32 **p, struct label **l,
static void __init build_r4000_tlb_load_handler(void)
{
u32 *p = handle_tlbl;
- struct label *l = labels;
- struct reloc *r = relocs;
+ struct uasm_label *l = labels;
+ struct uasm_reloc *r = relocs;
memset(handle_tlbl, 0, sizeof(handle_tlbl));
memset(labels, 0, sizeof(labels));
memset(relocs, 0, sizeof(relocs));
if (bcm1250_m3_war()) {
- i_MFC0(&p, K0, C0_BADVADDR);
- i_MFC0(&p, K1, C0_ENTRYHI);
- i_xor(&p, K0, K0, K1);
- i_SRL(&p, K0, K0, PAGE_SHIFT + 1);
- il_bnez(&p, &r, K0, label_leave);
- /* No need for i_nop */
+ UASM_i_MFC0(&p, K0, C0_BADVADDR);
+ UASM_i_MFC0(&p, K1, C0_ENTRYHI);
+ uasm_i_xor(&p, K0, K0, K1);
+ UASM_i_SRL(&p, K0, K0, PAGE_SHIFT + 1);
+ uasm_il_bnez(&p, &r, K0, label_leave);
+ /* No need for uasm_i_nop */
}
build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1);
@@ -1764,16 +1146,16 @@ static void __init build_r4000_tlb_load_handler(void)
build_make_valid(&p, &r, K0, K1);
build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1);
- l_nopage_tlbl(&l, p);
- i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff);
- i_nop(&p);
+ uasm_l_nopage_tlbl(&l, p);
+ uasm_i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff);
+ uasm_i_nop(&p);
if ((p - handle_tlbl) > FASTPATH_SIZE)
panic("TLB load handler fastpath space exceeded");
- resolve_relocs(relocs, labels);
- pr_info("Synthesized TLB load handler fastpath (%u instructions).\n",
- (unsigned int)(p - handle_tlbl));
+ uasm_resolve_relocs(relocs, labels);
+ pr_debug("Wrote TLB load handler fastpath (%u instructions).\n",
+ (unsigned int)(p - handle_tlbl));
dump_handler(handle_tlbl, ARRAY_SIZE(handle_tlbl));
}
@@ -1781,8 +1163,8 @@ static void __init build_r4000_tlb_load_handler(void)
static void __init build_r4000_tlb_store_handler(void)
{
u32 *p = handle_tlbs;
- struct label *l = labels;
- struct reloc *r = relocs;
+ struct uasm_label *l = labels;
+ struct uasm_reloc *r = relocs;
memset(handle_tlbs, 0, sizeof(handle_tlbs));
memset(labels, 0, sizeof(labels));
@@ -1795,16 +1177,16 @@ static void __init build_r4000_tlb_store_handler(void)
build_make_write(&p, &r, K0, K1);
build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1);
- l_nopage_tlbs(&l, p);
- i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
- i_nop(&p);
+ uasm_l_nopage_tlbs(&l, p);
+ uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
+ uasm_i_nop(&p);
if ((p - handle_tlbs) > FASTPATH_SIZE)
panic("TLB store handler fastpath space exceeded");
- resolve_relocs(relocs, labels);
- pr_info("Synthesized TLB store handler fastpath (%u instructions).\n",
- (unsigned int)(p - handle_tlbs));
+ uasm_resolve_relocs(relocs, labels);
+ pr_debug("Wrote TLB store handler fastpath (%u instructions).\n",
+ (unsigned int)(p - handle_tlbs));
dump_handler(handle_tlbs, ARRAY_SIZE(handle_tlbs));
}
@@ -1812,8 +1194,8 @@ static void __init build_r4000_tlb_store_handler(void)
static void __init build_r4000_tlb_modify_handler(void)
{
u32 *p = handle_tlbm;
- struct label *l = labels;
- struct reloc *r = relocs;
+ struct uasm_label *l = labels;
+ struct uasm_reloc *r = relocs;
memset(handle_tlbm, 0, sizeof(handle_tlbm));
memset(labels, 0, sizeof(labels));
@@ -1827,16 +1209,16 @@ static void __init build_r4000_tlb_modify_handler(void)
build_make_write(&p, &r, K0, K1);
build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1);
- l_nopage_tlbm(&l, p);
- i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
- i_nop(&p);
+ uasm_l_nopage_tlbm(&l, p);
+ uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
+ uasm_i_nop(&p);
if ((p - handle_tlbm) > FASTPATH_SIZE)
panic("TLB modify handler fastpath space exceeded");
- resolve_relocs(relocs, labels);
- pr_info("Synthesized TLB modify handler fastpath (%u instructions).\n",
- (unsigned int)(p - handle_tlbm));
+ uasm_resolve_relocs(relocs, labels);
+ pr_debug("Wrote TLB modify handler fastpath (%u instructions).\n",
+ (unsigned int)(p - handle_tlbm));
dump_handler(handle_tlbm, ARRAY_SIZE(handle_tlbm));
}
diff --git a/arch/mips/mm/uasm.c b/arch/mips/mm/uasm.c
new file mode 100644
index 0000000..5ee3a69
--- /dev/null
+++ b/arch/mips/mm/uasm.c
@@ -0,0 +1,576 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * A small micro-assembler. It is intentionally kept simple, does only
+ * support a subset of instructions, and does not try to hide pipeline
+ * effects like branch delay slots.
+ *
+ * Copyright (C) 2004, 2005, 2006, 2008 Thiemo Seufer
+ * Copyright (C) 2005, 2007 Maciej W. Rozycki
+ * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org)
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+
+#include <asm/inst.h>
+#include <asm/elf.h>
+#include <asm/bugs.h>
+
+#include "uasm.h"
+
+enum fields {
+ RS = 0x001,
+ RT = 0x002,
+ RD = 0x004,
+ RE = 0x008,
+ SIMM = 0x010,
+ UIMM = 0x020,
+ BIMM = 0x040,
+ JIMM = 0x080,
+ FUNC = 0x100,
+ SET = 0x200
+};
+
+#define OP_MASK 0x3f
+#define OP_SH 26
+#define RS_MASK 0x1f
+#define RS_SH 21
+#define RT_MASK 0x1f
+#define RT_SH 16
+#define RD_MASK 0x1f
+#define RD_SH 11
+#define RE_MASK 0x1f
+#define RE_SH 6
+#define IMM_MASK 0xffff
+#define IMM_SH 0
+#define JIMM_MASK 0x3ffffff
+#define JIMM_SH 0
+#define FUNC_MASK 0x3f
+#define FUNC_SH 0
+#define SET_MASK 0x7
+#define SET_SH 0
+
+enum opcode {
+ insn_invalid,
+ insn_addu, insn_addiu, insn_and, insn_andi, insn_beq,
+ insn_beql, insn_bgez, insn_bgezl, insn_bltz, insn_bltzl,
+ insn_bne, insn_daddu, insn_daddiu, insn_dmfc0, insn_dmtc0,
+ insn_dsll, insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32,
+ insn_dsubu, insn_eret, insn_j, insn_jal, insn_jr, insn_ld,
+ insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0, insn_mtc0,
+ insn_ori, insn_rfe, insn_sc, insn_scd, insn_sd, insn_sll,
+ insn_sra, insn_srl, insn_subu, insn_sw, insn_tlbp, insn_tlbwi,
+ insn_tlbwr, insn_xor, insn_xori
+};
+
+struct insn {
+ enum opcode opcode;
+ u32 match;
+ enum fields fields;
+};
+
+/* This macro sets the non-variable bits of an instruction. */
+#define M(a, b, c, d, e, f) \
+ ((a) << OP_SH \
+ | (b) << RS_SH \
+ | (c) << RT_SH \
+ | (d) << RD_SH \
+ | (e) << RE_SH \
+ | (f) << FUNC_SH)
+
+static struct insn insn_table[] __initdata = {
+ { insn_addiu, M(addiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
+ { insn_addu, M(spec_op, 0, 0, 0, 0, addu_op), RS | RT | RD },
+ { insn_and, M(spec_op, 0, 0, 0, 0, and_op), RS | RT | RD },
+ { insn_andi, M(andi_op, 0, 0, 0, 0, 0), RS | RT | UIMM },
+ { insn_beq, M(beq_op, 0, 0, 0, 0, 0), RS | RT | BIMM },
+ { insn_beql, M(beql_op, 0, 0, 0, 0, 0), RS | RT | BIMM },
+ { insn_bgez, M(bcond_op, 0, bgez_op, 0, 0, 0), RS | BIMM },
+ { insn_bgezl, M(bcond_op, 0, bgezl_op, 0, 0, 0), RS | BIMM },
+ { insn_bltz, M(bcond_op, 0, bltz_op, 0, 0, 0), RS | BIMM },
+ { insn_bltzl, M(bcond_op, 0, bltzl_op, 0, 0, 0), RS | BIMM },
+ { insn_bne, M(bne_op, 0, 0, 0, 0, 0), RS | RT | BIMM },
+ { insn_daddiu, M(daddiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
+ { insn_daddu, M(spec_op, 0, 0, 0, 0, daddu_op), RS | RT | RD },
+ { insn_dmfc0, M(cop0_op, dmfc_op, 0, 0, 0, 0), RT | RD | SET},
+ { insn_dmtc0, M(cop0_op, dmtc_op, 0, 0, 0, 0), RT | RD | SET},
+ { insn_dsll, M(spec_op, 0, 0, 0, 0, dsll_op), RT | RD | RE },
+ { insn_dsll32, M(spec_op, 0, 0, 0, 0, dsll32_op), RT | RD | RE },
+ { insn_dsra, M(spec_op, 0, 0, 0, 0, dsra_op), RT | RD | RE },
+ { insn_dsrl, M(spec_op, 0, 0, 0, 0, dsrl_op), RT | RD | RE },
+ { insn_dsrl32, M(spec_op, 0, 0, 0, 0, dsrl32_op), RT | RD | RE },
+ { insn_dsubu, M(spec_op, 0, 0, 0, 0, dsubu_op), RS | RT | RD },
+ { insn_eret, M(cop0_op, cop_op, 0, 0, 0, eret_op), 0 },
+ { insn_j, M(j_op, 0, 0, 0, 0, 0), JIMM },
+ { insn_jal, M(jal_op, 0, 0, 0, 0, 0), JIMM },
+ { insn_jr, M(spec_op, 0, 0, 0, 0, jr_op), RS },
+ { insn_ld, M(ld_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
+ { insn_ll, M(ll_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
+ { insn_lld, M(lld_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
+ { insn_lui, M(lui_op, 0, 0, 0, 0, 0), RT | SIMM },
+ { insn_lw, M(lw_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
+ { insn_mfc0, M(cop0_op, mfc_op, 0, 0, 0, 0), RT | RD | SET},
+ { insn_mtc0, M(cop0_op, mtc_op, 0, 0, 0, 0), RT | RD | SET},
+ { insn_ori, M(ori_op, 0, 0, 0, 0, 0), RS | RT | UIMM },
+ { insn_rfe, M(cop0_op, cop_op, 0, 0, 0, rfe_op), 0 },
+ { insn_sc, M(sc_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
+ { insn_scd, M(scd_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
+ { insn_sd, M(sd_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
+ { insn_sll, M(spec_op, 0, 0, 0, 0, sll_op), RT | RD | RE },
+ { insn_sra, M(spec_op, 0, 0, 0, 0, sra_op), RT | RD | RE },
+ { insn_srl, M(spec_op, 0, 0, 0, 0, srl_op), RT | RD | RE },
+ { insn_subu, M(spec_op, 0, 0, 0, 0, subu_op), RS | RT | RD },
+ { insn_sw, M(sw_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
+ { insn_tlbp, M(cop0_op, cop_op, 0, 0, 0, tlbp_op), 0 },
+ { insn_tlbwi, M(cop0_op, cop_op, 0, 0, 0, tlbwi_op), 0 },
+ { insn_tlbwr, M(cop0_op, cop_op, 0, 0, 0, tlbwr_op), 0 },
+ { insn_xor, M(spec_op, 0, 0, 0, 0, xor_op), RS | RT | RD },
+ { insn_xori, M(xori_op, 0, 0, 0, 0, 0), RS | RT | UIMM },
+ { insn_invalid, 0, 0 }
+};
+
+#undef M
+
+static inline __init u32 build_rs(u32 arg)
+{
+ if (arg & ~RS_MASK)
+ printk(KERN_WARNING "Micro-assembler field overflow\n");
+
+ return (arg & RS_MASK) << RS_SH;
+}
+
+static inline __init u32 build_rt(u32 arg)
+{
+ if (arg & ~RT_MASK)
+ printk(KERN_WARNING "Micro-assembler field overflow\n");
+
+ return (arg & RT_MASK) << RT_SH;
+}
+
+static inline __init u32 build_rd(u32 arg)
+{
+ if (arg & ~RD_MASK)
+ printk(KERN_WARNING "Micro-assembler field overflow\n");
+
+ return (arg & RD_MASK) << RD_SH;
+}
+
+static inline __init u32 build_re(u32 arg)
+{
+ if (arg & ~RE_MASK)
+ printk(KERN_WARNING "Micro-assembler field overflow\n");
+
+ return (arg & RE_MASK) << RE_SH;
+}
+
+static inline __init u32 build_simm(s32 arg)
+{
+ if (arg > 0x7fff || arg < -0x8000)
+ printk(KERN_WARNING "Micro-assembler field overflow\n");
+
+ return arg & 0xffff;
+}
+
+static inline __init u32 build_uimm(u32 arg)
+{
+ if (arg & ~IMM_MASK)
+ printk(KERN_WARNING "Micro-assembler field overflow\n");
+
+ return arg & IMM_MASK;
+}
+
+static inline __init u32 build_bimm(s32 arg)
+{
+ if (arg > 0x1ffff || arg < -0x20000)
+ printk(KERN_WARNING "Micro-assembler field overflow\n");
+
+ if (arg & 0x3)
+ printk(KERN_WARNING "Invalid micro-assembler branch target\n");
+
+ return ((arg < 0) ? (1 << 15) : 0) | ((arg >> 2) & 0x7fff);
+}
+
+static inline __init u32 build_jimm(u32 arg)
+{
+ if (arg & ~((JIMM_MASK) << 2))
+ printk(KERN_WARNING "Micro-assembler field overflow\n");
+
+ return (arg >> 2) & JIMM_MASK;
+}
+
+static inline __init u32 build_func(u32 arg)
+{
+ if (arg & ~FUNC_MASK)
+ printk(KERN_WARNING "Micro-assembler field overflow\n");
+
+ return arg & FUNC_MASK;
+}
+
+static inline __init u32 build_set(u32 arg)
+{
+ if (arg & ~SET_MASK)
+ printk(KERN_WARNING "Micro-assembler field overflow\n");
+
+ return arg & SET_MASK;
+}
+
+/*
+ * The order of opcode arguments is implicitly left to right,
+ * starting with RS and ending with FUNC or IMM.
+ */
+static void __init build_insn(u32 **buf, enum opcode opc, ...)
+{
+ struct insn *ip = NULL;
+ unsigned int i;
+ va_list ap;
+ u32 op;
+
+ for (i = 0; insn_table[i].opcode != insn_invalid; i++)
+ if (insn_table[i].opcode == opc) {
+ ip = &insn_table[i];
+ break;
+ }
+
+ if (!ip || (opc == insn_daddiu && r4k_daddiu_bug()))
+ panic("Unsupported Micro-assembler instruction %d", opc);
+
+ op = ip->match;
+ va_start(ap, opc);
+ if (ip->fields & RS)
+ op |= build_rs(va_arg(ap, u32));
+ if (ip->fields & RT)
+ op |= build_rt(va_arg(ap, u32));
+ if (ip->fields & RD)
+ op |= build_rd(va_arg(ap, u32));
+ if (ip->fields & RE)
+ op |= build_re(va_arg(ap, u32));
+ if (ip->fields & SIMM)
+ op |= build_simm(va_arg(ap, s32));
+ if (ip->fields & UIMM)
+ op |= build_uimm(va_arg(ap, u32));
+ if (ip->fields & BIMM)
+ op |= build_bimm(va_arg(ap, s32));
+ if (ip->fields & JIMM)
+ op |= build_jimm(va_arg(ap, u32));
+ if (ip->fields & FUNC)
+ op |= build_func(va_arg(ap, u32));
+ if (ip->fields & SET)
+ op |= build_set(va_arg(ap, u32));
+ va_end(ap);
+
+ **buf = op;
+ (*buf)++;
+}
+
+#define I_u1u2u3(op) \
+Ip_u1u2u3(op) \
+{ \
+ build_insn(buf, insn##op, a, b, c); \
+}
+
+#define I_u2u1u3(op) \
+Ip_u2u1u3(op) \
+{ \
+ build_insn(buf, insn##op, b, a, c); \
+}
+
+#define I_u3u1u2(op) \
+Ip_u3u1u2(op) \
+{ \
+ build_insn(buf, insn##op, b, c, a); \
+}
+
+#define I_u1u2s3(op) \
+Ip_u1u2s3(op) \
+{ \
+ build_insn(buf, insn##op, a, b, c); \
+}
+
+#define I_u2s3u1(op) \
+Ip_u2s3u1(op) \
+{ \
+ build_insn(buf, insn##op, c, a, b); \
+}
+
+#define I_u2u1s3(op) \
+Ip_u2u1s3(op) \
+{ \
+ build_insn(buf, insn##op, b, a, c); \
+}
+
+#define I_u1u2(op) \
+Ip_u1u2(op) \
+{ \
+ build_insn(buf, insn##op, a, b); \
+}
+
+#define I_u1s2(op) \
+Ip_u1s2(op) \
+{ \
+ build_insn(buf, insn##op, a, b); \
+}
+
+#define I_u1(op) \
+Ip_u1(op) \
+{ \
+ build_insn(buf, insn##op, a); \
+}
+
+#define I_0(op) \
+Ip_0(op) \
+{ \
+ build_insn(buf, insn##op); \
+}
+
+I_u2u1s3(_addiu)
+I_u3u1u2(_addu)
+I_u2u1u3(_andi)
+I_u3u1u2(_and)
+I_u1u2s3(_beq)
+I_u1u2s3(_beql)
+I_u1s2(_bgez)
+I_u1s2(_bgezl)
+I_u1s2(_bltz)
+I_u1s2(_bltzl)
+I_u1u2s3(_bne)
+I_u1u2u3(_dmfc0)
+I_u1u2u3(_dmtc0)
+I_u2u1s3(_daddiu)
+I_u3u1u2(_daddu)
+I_u2u1u3(_dsll)
+I_u2u1u3(_dsll32)
+I_u2u1u3(_dsra)
+I_u2u1u3(_dsrl)
+I_u2u1u3(_dsrl32)
+I_u3u1u2(_dsubu)
+I_0(_eret)
+I_u1(_j)
+I_u1(_jal)
+I_u1(_jr)
+I_u2s3u1(_ld)
+I_u2s3u1(_ll)
+I_u2s3u1(_lld)
+I_u1s2(_lui)
+I_u2s3u1(_lw)
+I_u1u2u3(_mfc0)
+I_u1u2u3(_mtc0)
+I_u2u1u3(_ori)
+I_0(_rfe)
+I_u2s3u1(_sc)
+I_u2s3u1(_scd)
+I_u2s3u1(_sd)
+I_u2u1u3(_sll)
+I_u2u1u3(_sra)
+I_u2u1u3(_srl)
+I_u3u1u2(_subu)
+I_u2s3u1(_sw)
+I_0(_tlbp)
+I_0(_tlbwi)
+I_0(_tlbwr)
+I_u3u1u2(_xor)
+I_u2u1u3(_xori)
+
+/* Handle labels. */
+void __init uasm_build_label(struct uasm_label **lab, u32 *addr, int lid)
+{
+ (*lab)->addr = addr;
+ (*lab)->lab = lid;
+ (*lab)++;
+}
+
+int __init uasm_in_compat_space_p(long addr)
+{
+ /* Is this address in 32bit compat space? */
+#ifdef CONFIG_64BIT
+ return (((addr) & 0xffffffff00000000L) == 0xffffffff00000000L);
+#else
+ return 1;
+#endif
+}
+
+int __init uasm_rel_highest(long val)
+{
+#ifdef CONFIG_64BIT
+ return ((((val + 0x800080008000L) >> 48) & 0xffff) ^ 0x8000) - 0x8000;
+#else
+ return 0;
+#endif
+}
+
+int __init uasm_rel_higher(long val)
+{
+#ifdef CONFIG_64BIT
+ return ((((val + 0x80008000L) >> 32) & 0xffff) ^ 0x8000) - 0x8000;
+#else
+ return 0;
+#endif
+}
+
+int __init uasm_rel_hi(long val)
+{
+ return ((((val + 0x8000L) >> 16) & 0xffff) ^ 0x8000) - 0x8000;
+}
+
+int __init uasm_rel_lo(long val)
+{
+ return ((val & 0xffff) ^ 0x8000) - 0x8000;
+}
+
+void __init UASM_i_LA_mostly(u32 **buf, unsigned int rs, long addr)
+{
+ if (!uasm_in_compat_space_p(addr)) {
+ uasm_i_lui(buf, rs, uasm_rel_highest(addr));
+ if (uasm_rel_higher(addr))
+ uasm_i_daddiu(buf, rs, rs, uasm_rel_higher(addr));
+ if (uasm_rel_hi(addr)) {
+ uasm_i_dsll(buf, rs, rs, 16);
+ uasm_i_daddiu(buf, rs, rs, uasm_rel_hi(addr));
+ uasm_i_dsll(buf, rs, rs, 16);
+ } else
+ uasm_i_dsll32(buf, rs, rs, 0);
+ } else
+ uasm_i_lui(buf, rs, uasm_rel_hi(addr));
+}
+
+void __init UASM_i_LA(u32 **buf, unsigned int rs, long addr)
+{
+ UASM_i_LA_mostly(buf, rs, addr);
+ if (uasm_rel_lo(addr)) {
+ if (!uasm_in_compat_space_p(addr))
+ uasm_i_daddiu(buf, rs, rs, uasm_rel_lo(addr));
+ else
+ uasm_i_addiu(buf, rs, rs, uasm_rel_lo(addr));
+ }
+}
+
+/* Handle relocations. */
+void __init
+uasm_r_mips_pc16(struct uasm_reloc **rel, u32 *addr, int lid)
+{
+ (*rel)->addr = addr;
+ (*rel)->type = R_MIPS_PC16;
+ (*rel)->lab = lid;
+ (*rel)++;
+}
+
+static inline void __init
+__resolve_relocs(struct uasm_reloc *rel, struct uasm_label *lab)
+{
+ long laddr = (long)lab->addr;
+ long raddr = (long)rel->addr;
+
+ switch (rel->type) {
+ case R_MIPS_PC16:
+ *rel->addr |= build_bimm(laddr - (raddr + 4));
+ break;
+
+ default:
+ panic("Unsupported Micro-assembler relocation %d",
+ rel->type);
+ }
+}
+
+void __init
+uasm_resolve_relocs(struct uasm_reloc *rel, struct uasm_label *lab)
+{
+ struct uasm_label *l;
+
+ for (; rel->lab != UASM_LABEL_INVALID; rel++)
+ for (l = lab; l->lab != UASM_LABEL_INVALID; l++)
+ if (rel->lab == l->lab)
+ __resolve_relocs(rel, l);
+}
+
+void __init
+uasm_move_relocs(struct uasm_reloc *rel, u32 *first, u32 *end, long off)
+{
+ for (; rel->lab != UASM_LABEL_INVALID; rel++)
+ if (rel->addr >= first && rel->addr < end)
+ rel->addr += off;
+}
+
+void __init
+uasm_move_labels(struct uasm_label *lab, u32 *first, u32 *end, long off)
+{
+ for (; lab->lab != UASM_LABEL_INVALID; lab++)
+ if (lab->addr >= first && lab->addr < end)
+ lab->addr += off;
+}
+
+void __init
+uasm_copy_handler(struct uasm_reloc *rel, struct uasm_label *lab, u32 *first,
+ u32 *end, u32 *target)
+{
+ long off = (long)(target - first);
+
+ memcpy(target, first, (end - first) * sizeof(u32));
+
+ uasm_move_relocs(rel, first, end, off);
+ uasm_move_labels(lab, first, end, off);
+}
+
+int __init uasm_insn_has_bdelay(struct uasm_reloc *rel, u32 *addr)
+{
+ for (; rel->lab != UASM_LABEL_INVALID; rel++) {
+ if (rel->addr == addr
+ && (rel->type == R_MIPS_PC16
+ || rel->type == R_MIPS_26))
+ return 1;
+ }
+
+ return 0;
+}
+
+/* Convenience functions for labeled branches. */
+void __init
+uasm_il_bltz(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid)
+{
+ uasm_r_mips_pc16(r, *p, lid);
+ uasm_i_bltz(p, reg, 0);
+}
+
+void __init
+uasm_il_b(u32 **p, struct uasm_reloc **r, int lid)
+{
+ uasm_r_mips_pc16(r, *p, lid);
+ uasm_i_b(p, 0);
+}
+
+void __init
+uasm_il_beqz(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid)
+{
+ uasm_r_mips_pc16(r, *p, lid);
+ uasm_i_beqz(p, reg, 0);
+}
+
+void __init
+uasm_il_beqzl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid)
+{
+ uasm_r_mips_pc16(r, *p, lid);
+ uasm_i_beqzl(p, reg, 0);
+}
+
+void __init
+uasm_il_bnez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid)
+{
+ uasm_r_mips_pc16(r, *p, lid);
+ uasm_i_bnez(p, reg, 0);
+}
+
+void __init
+uasm_il_bgezl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid)
+{
+ uasm_r_mips_pc16(r, *p, lid);
+ uasm_i_bgezl(p, reg, 0);
+}
+
+void __init
+uasm_il_bgez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid)
+{
+ uasm_r_mips_pc16(r, *p, lid);
+ uasm_i_bgez(p, reg, 0);
+}
diff --git a/arch/mips/mm/uasm.h b/arch/mips/mm/uasm.h
new file mode 100644
index 0000000..a10fc11
--- /dev/null
+++ b/arch/mips/mm/uasm.h
@@ -0,0 +1,192 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2004, 2005, 2006, 2008 Thiemo Seufer
+ * Copyright (C) 2005 Maciej W. Rozycki
+ * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org)
+ */
+
+#include <linux/types.h>
+
+#define Ip_u1u2u3(op) \
+void __init \
+uasm_i##op(u32 **buf, unsigned int a, unsigned int b, unsigned int c)
+
+#define Ip_u2u1u3(op) \
+void __init \
+uasm_i##op(u32 **buf, unsigned int a, unsigned int b, unsigned int c)
+
+#define Ip_u3u1u2(op) \
+void __init \
+uasm_i##op(u32 **buf, unsigned int a, unsigned int b, unsigned int c)
+
+#define Ip_u1u2s3(op) \
+void __init \
+uasm_i##op(u32 **buf, unsigned int a, unsigned int b, signed int c)
+
+#define Ip_u2s3u1(op) \
+void __init \
+uasm_i##op(u32 **buf, unsigned int a, signed int b, unsigned int c)
+
+#define Ip_u2u1s3(op) \
+void __init \
+uasm_i##op(u32 **buf, unsigned int a, unsigned int b, signed int c)
+
+#define Ip_u1u2(op) \
+void __init uasm_i##op(u32 **buf, unsigned int a, unsigned int b)
+
+#define Ip_u1s2(op) \
+void __init uasm_i##op(u32 **buf, unsigned int a, signed int b)
+
+#define Ip_u1(op) void __init uasm_i##op(u32 **buf, unsigned int a)
+
+#define Ip_0(op) void __init uasm_i##op(u32 **buf)
+
+Ip_u2u1s3(_addiu);
+Ip_u3u1u2(_addu);
+Ip_u2u1u3(_andi);
+Ip_u3u1u2(_and);
+Ip_u1u2s3(_beq);
+Ip_u1u2s3(_beql);
+Ip_u1s2(_bgez);
+Ip_u1s2(_bgezl);
+Ip_u1s2(_bltz);
+Ip_u1s2(_bltzl);
+Ip_u1u2s3(_bne);
+Ip_u1u2u3(_dmfc0);
+Ip_u1u2u3(_dmtc0);
+Ip_u2u1s3(_daddiu);
+Ip_u3u1u2(_daddu);
+Ip_u2u1u3(_dsll);
+Ip_u2u1u3(_dsll32);
+Ip_u2u1u3(_dsra);
+Ip_u2u1u3(_dsrl);
+Ip_u2u1u3(_dsrl32);
+Ip_u3u1u2(_dsubu);
+Ip_0(_eret);
+Ip_u1(_j);
+Ip_u1(_jal);
+Ip_u1(_jr);
+Ip_u2s3u1(_ld);
+Ip_u2s3u1(_ll);
+Ip_u2s3u1(_lld);
+Ip_u1s2(_lui);
+Ip_u2s3u1(_lw);
+Ip_u1u2u3(_mfc0);
+Ip_u1u2u3(_mtc0);
+Ip_u2u1u3(_ori);
+Ip_0(_rfe);
+Ip_u2s3u1(_sc);
+Ip_u2s3u1(_scd);
+Ip_u2s3u1(_sd);
+Ip_u2u1u3(_sll);
+Ip_u2u1u3(_sra);
+Ip_u2u1u3(_srl);
+Ip_u3u1u2(_subu);
+Ip_u2s3u1(_sw);
+Ip_0(_tlbp);
+Ip_0(_tlbwi);
+Ip_0(_tlbwr);
+Ip_u3u1u2(_xor);
+Ip_u2u1u3(_xori);
+
+/* Handle labels. */
+struct uasm_label {
+ u32 *addr;
+ int lab;
+};
+
+void __init uasm_build_label(struct uasm_label **lab, u32 *addr, int lid);
+#ifdef CONFIG_64BIT
+int __init uasm_in_compat_space_p(long addr);
+int __init uasm_rel_highest(long val);
+int __init uasm_rel_higher(long val);
+#endif
+int __init uasm_rel_hi(long val);
+int __init uasm_rel_lo(long val);
+void __init UASM_i_LA_mostly(u32 **buf, unsigned int rs, long addr);
+void __init UASM_i_LA(u32 **buf, unsigned int rs, long addr);
+
+#define UASM_L_LA(lb) \
+static inline void __init uasm_l##lb(struct uasm_label **lab, u32 *addr) \
+{ \
+ uasm_build_label(lab, addr, label##lb); \
+}
+
+/* convenience macros for instructions */
+#ifdef CONFIG_64BIT
+# define UASM_i_LW(buf, rs, rt, off) uasm_i_ld(buf, rs, rt, off)
+# define UASM_i_SW(buf, rs, rt, off) uasm_i_sd(buf, rs, rt, off)
+# define UASM_i_SLL(buf, rs, rt, sh) uasm_i_dsll(buf, rs, rt, sh)
+# define UASM_i_SRA(buf, rs, rt, sh) uasm_i_dsra(buf, rs, rt, sh)
+# define UASM_i_SRL(buf, rs, rt, sh) uasm_i_dsrl(buf, rs, rt, sh)
+# define UASM_i_MFC0(buf, rt, rd...) uasm_i_dmfc0(buf, rt, rd)
+# define UASM_i_MTC0(buf, rt, rd...) uasm_i_dmtc0(buf, rt, rd)
+# define UASM_i_ADDIU(buf, rs, rt, val) uasm_i_daddiu(buf, rs, rt, val)
+# define UASM_i_ADDU(buf, rs, rt, rd) uasm_i_daddu(buf, rs, rt, rd)
+# define UASM_i_SUBU(buf, rs, rt, rd) uasm_i_dsubu(buf, rs, rt, rd)
+# define UASM_i_LL(buf, rs, rt, off) uasm_i_lld(buf, rs, rt, off)
+# define UASM_i_SC(buf, rs, rt, off) uasm_i_scd(buf, rs, rt, off)
+#else
+# define UASM_i_LW(buf, rs, rt, off) uasm_i_lw(buf, rs, rt, off)
+# define UASM_i_SW(buf, rs, rt, off) uasm_i_sw(buf, rs, rt, off)
+# define UASM_i_SLL(buf, rs, rt, sh) uasm_i_sll(buf, rs, rt, sh)
+# define UASM_i_SRA(buf, rs, rt, sh) uasm_i_sra(buf, rs, rt, sh)
+# define UASM_i_SRL(buf, rs, rt, sh) uasm_i_srl(buf, rs, rt, sh)
+# define UASM_i_MFC0(buf, rt, rd...) uasm_i_mfc0(buf, rt, rd)
+# define UASM_i_MTC0(buf, rt, rd...) uasm_i_mtc0(buf, rt, rd)
+# define UASM_i_ADDIU(buf, rs, rt, val) uasm_i_addiu(buf, rs, rt, val)
+# define UASM_i_ADDU(buf, rs, rt, rd) uasm_i_addu(buf, rs, rt, rd)
+# define UASM_i_SUBU(buf, rs, rt, rd) uasm_i_subu(buf, rs, rt, rd)
+# define UASM_i_LL(buf, rs, rt, off) uasm_i_ll(buf, rs, rt, off)
+# define UASM_i_SC(buf, rs, rt, off) uasm_i_sc(buf, rs, rt, off)
+#endif
+
+#define uasm_i_b(buf, off) uasm_i_beq(buf, 0, 0, off)
+#define uasm_i_beqz(buf, rs, off) uasm_i_beq(buf, rs, 0, off)
+#define uasm_i_beqzl(buf, rs, off) uasm_i_beql(buf, rs, 0, off)
+#define uasm_i_bnez(buf, rs, off) uasm_i_bne(buf, rs, 0, off)
+#define uasm_i_bnezl(buf, rs, off) uasm_i_bnel(buf, rs, 0, off)
+#define uasm_i_move(buf, a, b) UASM_i_ADDU(buf, a, 0, b)
+#define uasm_i_nop(buf) uasm_i_sll(buf, 0, 0, 0)
+#define uasm_i_ssnop(buf) uasm_i_sll(buf, 0, 0, 1)
+#define uasm_i_ehb(buf) uasm_i_sll(buf, 0, 0, 3)
+
+/* Handle relocations. */
+struct uasm_reloc {
+ u32 *addr;
+ unsigned int type;
+ int lab;
+};
+
+/* This is zero so we can use zeroed label arrays. */
+#define UASM_LABEL_INVALID 0
+
+void __init uasm_r_mips_pc16(struct uasm_reloc **rel, u32 *addr, int lid);
+void __init
+uasm_resolve_relocs(struct uasm_reloc *rel, struct uasm_label *lab);
+void __init
+uasm_move_relocs(struct uasm_reloc *rel, u32 *first, u32 *end, long off);
+void __init
+uasm_move_labels(struct uasm_label *lab, u32 *first, u32 *end, long off);
+void __init
+uasm_copy_handler(struct uasm_reloc *rel, struct uasm_label *lab, u32 *first,
+ u32 *end, u32 *target);
+int __init uasm_insn_has_bdelay(struct uasm_reloc *rel, u32 *addr);
+
+/* Convenience functions for labeled branches. */
+void __init
+uasm_il_bltz(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
+void __init uasm_il_b(u32 **p, struct uasm_reloc **r, int lid);
+void __init
+uasm_il_beqz(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
+void __init
+uasm_il_beqzl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
+void __init
+uasm_il_bnez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
+void __init
+uasm_il_bgezl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
+void __init
+uasm_il_bgez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
^ permalink raw reply related [flat|nested] 38+ messages in thread
* Re: Split the micro-assembler from tlbex.c (was: Re: your mail)
2008-01-28 20:05 ` Split the micro-assembler from tlbex.c (was: Re: your mail) Thiemo Seufer
@ 2008-01-28 22:53 ` Ralf Baechle
0 siblings, 0 replies; 38+ messages in thread
From: Ralf Baechle @ 2008-01-28 22:53 UTC (permalink / raw)
To: Thiemo Seufer; +Cc: linux-mips
On Mon, Jan 28, 2008 at 08:05:38PM +0000, Thiemo Seufer wrote:
> Split the micro-assembler from tlbex.c.
>
> This patch moves the micro-assembler in a separate implementation, as
> it is useful for further run-time optimizations. The only change in
> behaviour is cutting down printk noise at kernel startup time.
>
> Checkpatch complains about macro parameters which aren't protected by
> parentheses. I believe this is a flaw in checkpatch, the paste operator
> used in those macros won't work with parenthesised parameters.
>
> Signed-off-by: Thiemo Seufer <ths@networkno.de>
This one works, thanks.
Ralf
^ permalink raw reply [flat|nested] 38+ messages in thread
* (no subject)
@ 2020-05-06 5:52 Jiaxun Yang
2020-05-07 11:00 ` your mail Thomas Bogendoerfer
0 siblings, 1 reply; 38+ messages in thread
From: Jiaxun Yang @ 2020-05-06 5:52 UTC (permalink / raw)
To: linux-mips
Cc: Jiaxun Yang, clang-built-linux, Maciej W . Rozycki, Fangrui Song,
Kees Cook, Nathan Chancellor, Thomas Bogendoerfer, Paul Burton,
Masahiro Yamada, Jouni Hogander, Kevin Darbyshire-Bryant,
Borislav Petkov, Heiko Carstens, linux-kernel
Subject: [PATCH v6] MIPS: Truncate link address into 32bit for 32bit kernel
In-Reply-To: <20200413062651.3992652-1-jiaxun.yang@flygoat.com>
LLD failed to link vmlinux with 64bit load address for 32bit ELF
while bfd will strip 64bit address into 32bit silently.
To fix LLD build, we should truncate load address provided by platform
into 32bit for 32bit kernel.
Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Link: https://github.com/ClangBuiltLinux/linux/issues/786
Link: https://sourceware.org/bugzilla/show_bug.cgi?id=25784
Reviewed-by: Fangrui Song <maskray@google.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Tested-by: Nathan Chancellor <natechancellor@gmail.com>
Cc: Maciej W. Rozycki <macro@linux-mips.org>
---
V2: Take MaskRay's shell magic.
V3: After spent an hour on dealing with special character issue in
Makefile, I gave up to do shell hacks and write a util in C instead.
Thanks Maciej for pointing out Makefile variable problem.
v4: Finally we managed to find a Makefile method to do it properly
thanks to Kees. As it's too far from the initial version, I removed
Review & Test tag from Nick and Fangrui and Cc instead.
v5: Care vmlinuz as well.
v6: Rename to LIKER_LOAD_ADDRESS
---
arch/mips/Makefile | 13 ++++++++++++-
arch/mips/boot/compressed/Makefile | 2 +-
arch/mips/kernel/vmlinux.lds.S | 2 +-
3 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index e1c44aed8156..68c0f22fefc0 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -288,12 +288,23 @@ ifdef CONFIG_64BIT
endif
endif
+# When linking a 32-bit executable the LLVM linker cannot cope with a
+# 32-bit load address that has been sign-extended to 64 bits. Simply
+# remove the upper 32 bits then, as it is safe to do so with other
+# linkers.
+ifdef CONFIG_64BIT
+ load-ld = $(load-y)
+else
+ load-ld = $(subst 0xffffffff,0x,$(load-y))
+endif
+
KBUILD_AFLAGS += $(cflags-y)
KBUILD_CFLAGS += $(cflags-y)
-KBUILD_CPPFLAGS += -DVMLINUX_LOAD_ADDRESS=$(load-y)
+KBUILD_CPPFLAGS += -DVMLINUX_LOAD_ADDRESS=$(load-y) -DLINKER_LOAD_ADDRESS=$(load-ld)
KBUILD_CPPFLAGS += -DDATAOFFSET=$(if $(dataoffset-y),$(dataoffset-y),0)
bootvars-y = VMLINUX_LOAD_ADDRESS=$(load-y) \
+ LINKER_LOAD_ADDRESS=$(load-ld) \
VMLINUX_ENTRY_ADDRESS=$(entry-y) \
PLATFORM="$(platform-y)" \
ITS_INPUTS="$(its-y)"
diff --git a/arch/mips/boot/compressed/Makefile b/arch/mips/boot/compressed/Makefile
index 0df0ee8a298d..3d391256ab7e 100644
--- a/arch/mips/boot/compressed/Makefile
+++ b/arch/mips/boot/compressed/Makefile
@@ -90,7 +90,7 @@ ifneq ($(zload-y),)
VMLINUZ_LOAD_ADDRESS := $(zload-y)
else
VMLINUZ_LOAD_ADDRESS = $(shell $(obj)/calc_vmlinuz_load_addr \
- $(obj)/vmlinux.bin $(VMLINUX_LOAD_ADDRESS))
+ $(obj)/vmlinux.bin $(LINKER_LOAD_ADDRESS))
endif
UIMAGE_LOADADDR = $(VMLINUZ_LOAD_ADDRESS)
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
index a5f00ec73ea6..5226cd8e4bee 100644
--- a/arch/mips/kernel/vmlinux.lds.S
+++ b/arch/mips/kernel/vmlinux.lds.S
@@ -55,7 +55,7 @@ SECTIONS
/* . = 0xa800000000300000; */
. = 0xffffffff80300000;
#endif
- . = VMLINUX_LOAD_ADDRESS;
+ . = LINKER_LOAD_ADDRESS;
/* read-only */
_text = .; /* Text and read-only data */
.text : {
^ permalink raw reply related [flat|nested] 38+ messages in thread
* Re: your mail
2020-05-06 5:52 Jiaxun Yang
@ 2020-05-07 11:00 ` Thomas Bogendoerfer
0 siblings, 0 replies; 38+ messages in thread
From: Thomas Bogendoerfer @ 2020-05-07 11:00 UTC (permalink / raw)
To: Jiaxun Yang
Cc: linux-mips, clang-built-linux, Maciej W . Rozycki, Fangrui Song,
Kees Cook, Nathan Chancellor, Paul Burton, Masahiro Yamada,
Jouni Hogander, Kevin Darbyshire-Bryant, Borislav Petkov,
Heiko Carstens, linux-kernel
On Wed, May 06, 2020 at 01:52:45PM +0800, Jiaxun Yang wrote:
> Subject: [PATCH v6] MIPS: Truncate link address into 32bit for 32bit kernel
> In-Reply-To: <20200413062651.3992652-1-jiaxun.yang@flygoat.com>
>
> LLD failed to link vmlinux with 64bit load address for 32bit ELF
> while bfd will strip 64bit address into 32bit silently.
> To fix LLD build, we should truncate load address provided by platform
> into 32bit for 32bit kernel.
>
> Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> Link: https://github.com/ClangBuiltLinux/linux/issues/786
> Link: https://sourceware.org/bugzilla/show_bug.cgi?id=25784
> Reviewed-by: Fangrui Song <maskray@google.com>
> Reviewed-by: Kees Cook <keescook@chromium.org>
> Tested-by: Nathan Chancellor <natechancellor@gmail.com>
> Cc: Maciej W. Rozycki <macro@linux-mips.org>
> ---
> V2: Take MaskRay's shell magic.
>
> V3: After spent an hour on dealing with special character issue in
> Makefile, I gave up to do shell hacks and write a util in C instead.
> Thanks Maciej for pointing out Makefile variable problem.
>
> v4: Finally we managed to find a Makefile method to do it properly
> thanks to Kees. As it's too far from the initial version, I removed
> Review & Test tag from Nick and Fangrui and Cc instead.
>
> v5: Care vmlinuz as well.
>
> v6: Rename to LIKER_LOAD_ADDRESS
> ---
> arch/mips/Makefile | 13 ++++++++++++-
> arch/mips/boot/compressed/Makefile | 2 +-
> arch/mips/kernel/vmlinux.lds.S | 2 +-
> 3 files changed, 14 insertions(+), 3 deletions(-)
applied to mips-next.
Thomas.
--
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea. [ RFC1925, 2.3 ]
^ permalink raw reply [flat|nested] 38+ messages in thread
* (no subject)
@ 2018-08-27 14:50 Christoph Hellwig
2018-08-31 20:23 ` your mail Paul Burton
0 siblings, 1 reply; 38+ messages in thread
From: Christoph Hellwig @ 2018-08-27 14:50 UTC (permalink / raw)
To: iommu
Cc: Marek Szyprowski, Robin Murphy, Paul Burton, Greg Kroah-Hartman,
linux-mips, linux-kernel
Subject: [RFC] merge dma_direct_ops and dma_noncoherent_ops
While most architectures are either always or never dma coherent for a
given build, the arm, arm64, mips and soon arc architectures can have
different dma coherent settings on a per-device basis. Additionally
some mips builds can decide at boot time if dma is coherent or not.
I've started to look into handling noncoherent dma in swiotlb, and
moving the dma-iommu ops into common code [1], and for that we need a
generic way to check if a given device is coherent or not. Moving
this flag into struct device also simplifies the conditionally coherent
architecture implementations.
These patches are also available in a git tree given that they have
a few previous posted dependencies:
git://git.infradead.org/users/hch/misc.git dma-direct-noncoherent-merge
Gitweb:
http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/dma-direct-noncoherent-merge
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: your mail
2018-08-27 14:50 Christoph Hellwig
@ 2018-08-31 20:23 ` Paul Burton
0 siblings, 0 replies; 38+ messages in thread
From: Paul Burton @ 2018-08-31 20:23 UTC (permalink / raw)
To: Christoph Hellwig
Cc: iommu, Marek Szyprowski, Robin Murphy, Greg Kroah-Hartman,
linux-mips, linux-kernel
Hi Christoph,
On Mon, Aug 27, 2018 at 04:50:27PM +0200, Christoph Hellwig wrote:
> Subject: [RFC] merge dma_direct_ops and dma_noncoherent_ops
>
> While most architectures are either always or never dma coherent for a
> given build, the arm, arm64, mips and soon arc architectures can have
> different dma coherent settings on a per-device basis. Additionally
> some mips builds can decide at boot time if dma is coherent or not.
>
> I've started to look into handling noncoherent dma in swiotlb, and
> moving the dma-iommu ops into common code [1], and for that we need a
> generic way to check if a given device is coherent or not. Moving
> this flag into struct device also simplifies the conditionally coherent
> architecture implementations.
>
> These patches are also available in a git tree given that they have
> a few previous posted dependencies:
>
> git://git.infradead.org/users/hch/misc.git dma-direct-noncoherent-merge
>
> Gitweb:
>
> http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/dma-direct-noncoherent-merge
Apart from the nits in patch 2, these look sane to me from a MIPS
perspective, so for patches 1-4:
Acked-by: Paul Burton <paul.burton@mips.com> # MIPS parts
Thanks,
Paul
^ permalink raw reply [flat|nested] 38+ messages in thread
* [PATCH 00/14] Enable SD/MMC on JZ4780 SoCs
@ 2018-03-09 15:12 Ezequiel Garcia
2018-03-09 15:12 ` [PATCH 08/14] mmc: jz4740: Add support for the JZ4780 Ezequiel Garcia
0 siblings, 1 reply; 38+ messages in thread
From: Ezequiel Garcia @ 2018-03-09 15:12 UTC (permalink / raw)
To: Ulf Hansson, Paul Cercueil
Cc: linux-mmc, linux-mips, James Hogan, Ezequiel Garcia
This patchset adds support for SD/MMC on JZ4780 based
platforms, such as the MIPS Creator CI20 board.
Most of the work has been done by Alex, Paul and Zubair,
while I've only prepared the upstream submission, cleaned
some patches, and written some commit logs where needed.
All praises should go to them, all rants to me.
The series is based on v4.16-rc4.
Alex Smith (3):
mmc: jz4740: Set clock rate to mmc->f_max rather than JZ_MMC_CLK_RATE
mmc: jz4740: Add support for the JZ4780
mmc: jz4740: Fix race condition in IRQ mask update
Ezequiel Garcia (9):
mmc: jz4780: Order headers alphabetically
mmc: jz4740: Use dev_get_platdata
mmc: jz4740: Introduce devicetree probe
mmc: dt-bindings: add MMC support to JZ4740 SoC
mmc: jz4740: Use dma_request_chan()
MIPS: dts: jz4780: Add DMA controller node to the devicetree
MIPS: dts: jz4780: Add MMC controller node to the devicetree
MIPS: dts: ci20: Enable DMA and MMC in the devicetree
MIPS: configs: ci20: Enable DMA and MMC support
Paul Cercueil (1):
mmc: jz4740: Fix error exit path in driver's probe
Zubair Lutfullah Kakakhel (1):
mmc: jz4740: Reset the device requesting the interrupt
Documentation/devicetree/bindings/mmc/jz4740.txt | 38 ++++
arch/mips/boot/dts/ingenic/ci20.dts | 38 ++++
arch/mips/boot/dts/ingenic/jz4780.dtsi | 54 ++++++
arch/mips/configs/ci20_defconfig | 3 +
drivers/mmc/host/Kconfig | 2 +-
drivers/mmc/host/jz4740_mmc.c | 232 ++++++++++++++++-------
include/dt-bindings/dma/jz4780-dma.h | 49 +++++
7 files changed, 349 insertions(+), 67 deletions(-)
create mode 100644 Documentation/devicetree/bindings/mmc/jz4740.txt
create mode 100644 include/dt-bindings/dma/jz4780-dma.h
--
2.16.2
^ permalink raw reply [flat|nested] 38+ messages in thread
* [PATCH 08/14] mmc: jz4740: Add support for the JZ4780
2018-03-09 15:12 [PATCH 00/14] Enable SD/MMC on JZ4780 SoCs Ezequiel Garcia
@ 2018-03-09 15:12 ` Ezequiel Garcia
2018-03-09 17:51 ` [PATCH 08/14] mmc: jz4740: Add support for the JZ4780, Paul Cercueil
0 siblings, 1 reply; 38+ messages in thread
From: Ezequiel Garcia @ 2018-03-09 15:12 UTC (permalink / raw)
To: Ulf Hansson, Paul Cercueil
Cc: linux-mmc, linux-mips, James Hogan, Alex Smith, Ezequiel Garcia
From: Alex Smith <alex.smith@imgtec.com>
Add support for the JZ4780 MMC controller to the jz47xx_mmc driver. There
are a few minor differences from the 4740 to the 4780 that need to be
handled, but otherwise the controllers behave the same. The IREG and IMASK
registers are expanded to 32 bits. Additionally, some error conditions are
now reported in both STATUS and IREG. Writing IREG before reading STATUS
causes the bits in STATUS to be cleared, so STATUS must be read first to
ensure we see and report error conditions correctly.
Signed-off-by: Alex Smith <alex.smith@imgtec.com>
Signed-off-by: Paul Cercueil <paul@crapouillou.net>
[Ezequiel: rebase and introduce register accessors]
Signed-off-by: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
---
drivers/mmc/host/Kconfig | 2 +-
drivers/mmc/host/jz4740_mmc.c | 111 ++++++++++++++++++++++++++++++++++--------
2 files changed, 93 insertions(+), 20 deletions(-)
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 620c2d90a646..7dd5169a2dfb 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -767,7 +767,7 @@ config MMC_SH_MMCIF
config MMC_JZ4740
tristate "JZ4740 SD/Multimedia Card Interface support"
- depends on MACH_JZ4740
+ depends on MACH_JZ4740 || MACH_JZ4780
help
This selects support for the SD/MMC controller on Ingenic JZ4740
SoCs.
diff --git a/drivers/mmc/host/jz4740_mmc.c b/drivers/mmc/host/jz4740_mmc.c
index 7d4dcce76cd8..bb1b9114ef53 100644
--- a/drivers/mmc/host/jz4740_mmc.c
+++ b/drivers/mmc/host/jz4740_mmc.c
@@ -1,5 +1,7 @@
/*
* Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
+ * Copyright (C) 2013, Imagination Technologies
+ *
* JZ4740 SD/MMC controller driver
*
* This program is free software; you can redistribute it and/or modify it
@@ -52,6 +54,7 @@
#define JZ_REG_MMC_RESP_FIFO 0x34
#define JZ_REG_MMC_RXFIFO 0x38
#define JZ_REG_MMC_TXFIFO 0x3C
+#define JZ_REG_MMC_DMAC 0x44
#define JZ_MMC_STRPCL_EXIT_MULTIPLE BIT(7)
#define JZ_MMC_STRPCL_EXIT_TRANSFER BIT(6)
@@ -105,11 +108,15 @@
#define JZ_MMC_IRQ_PRG_DONE BIT(1)
#define JZ_MMC_IRQ_DATA_TRAN_DONE BIT(0)
+#define JZ_MMC_DMAC_DMA_SEL BIT(1)
+#define JZ_MMC_DMAC_DMA_EN BIT(0)
#define JZ_MMC_CLK_RATE 24000000
enum jz4740_mmc_version {
JZ_MMC_JZ4740,
+ JZ_MMC_JZ4750,
+ JZ_MMC_JZ4780,
};
enum jz4740_mmc_state {
@@ -144,7 +151,7 @@ struct jz4740_mmc_host {
uint32_t cmdat;
- uint16_t irq_mask;
+ uint32_t irq_mask;
spinlock_t lock;
@@ -164,8 +171,46 @@ struct jz4740_mmc_host {
* trigger is when data words in MSC_TXFIFO is < 8.
*/
#define JZ4740_MMC_FIFO_HALF_SIZE 8
+
+ void (*write_irq_mask)(struct jz4740_mmc_host *host, uint32_t val);
+ void (*write_irq_reg)(struct jz4740_mmc_host *host, uint32_t val);
+ uint32_t (*read_irq_reg)(struct jz4740_mmc_host *host);
};
+static void jz4750_mmc_write_irq_mask(struct jz4740_mmc_host *host,
+ uint32_t val)
+{
+ return writel(val, host->base + JZ_REG_MMC_IMASK);
+}
+
+static void jz4740_mmc_write_irq_mask(struct jz4740_mmc_host *host,
+ uint32_t val)
+{
+ return writew(val, host->base + JZ_REG_MMC_IMASK);
+}
+
+static void jz4740_mmc_write_irq_reg(struct jz4740_mmc_host *host,
+ uint32_t val)
+{
+ return writew(val, host->base + JZ_REG_MMC_IREG);
+}
+
+static uint32_t jz4740_mmc_read_irq_reg(struct jz4740_mmc_host *host)
+{
+ return readw(host->base + JZ_REG_MMC_IREG);
+}
+
+static void jz4780_mmc_write_irq_reg(struct jz4740_mmc_host *host, uint32_t val)
+{
+ return writel(val, host->base + JZ_REG_MMC_IREG);
+}
+
+/* In the 4780 onwards, IREG is expanded to 32 bits. */
+static uint32_t jz4780_mmc_read_irq_reg(struct jz4740_mmc_host *host)
+{
+ return readl(host->base + JZ_REG_MMC_IREG);
+}
+
/*----------------------------------------------------------------------------*/
/* DMA infrastructure */
@@ -371,7 +416,7 @@ static void jz4740_mmc_set_irq_enabled(struct jz4740_mmc_host *host,
host->irq_mask |= irq;
spin_unlock_irqrestore(&host->lock, flags);
- writew(host->irq_mask, host->base + JZ_REG_MMC_IMASK);
+ host->write_irq_mask(host, host->irq_mask);
}
static void jz4740_mmc_clock_enable(struct jz4740_mmc_host *host,
@@ -422,10 +467,10 @@ static unsigned int jz4740_mmc_poll_irq(struct jz4740_mmc_host *host,
unsigned int irq)
{
unsigned int timeout = 0x800;
- uint16_t status;
+ uint32_t status;
do {
- status = readw(host->base + JZ_REG_MMC_IREG);
+ status = host->read_irq_reg(host);
} while (!(status & irq) && --timeout);
if (timeout == 0) {
@@ -525,7 +570,7 @@ static bool jz4740_mmc_read_data(struct jz4740_mmc_host *host,
void __iomem *fifo_addr = host->base + JZ_REG_MMC_RXFIFO;
uint32_t *buf;
uint32_t d;
- uint16_t status;
+ uint32_t status;
size_t i, j;
unsigned int timeout;
@@ -661,8 +706,25 @@ static void jz4740_mmc_send_command(struct jz4740_mmc_host *host,
cmdat |= JZ_MMC_CMDAT_DATA_EN;
if (cmd->data->flags & MMC_DATA_WRITE)
cmdat |= JZ_MMC_CMDAT_WRITE;
- if (host->use_dma)
- cmdat |= JZ_MMC_CMDAT_DMA_EN;
+ if (host->use_dma) {
+ /*
+ * The 4780's MMC controller has integrated DMA ability
+ * in addition to being able to use the external DMA
+ * controller. It moves DMA control bits to a separate
+ * register. The DMA_SEL bit chooses the external
+ * controller over the integrated one. Earlier SoCs
+ * can only use the external controller, and have a
+ * single DMA enable bit in CMDAT.
+ */
+ if (host->version >= JZ_MMC_JZ4780) {
+ writel(JZ_MMC_DMAC_DMA_EN | JZ_MMC_DMAC_DMA_SEL,
+ host->base + JZ_REG_MMC_DMAC);
+ } else {
+ cmdat |= JZ_MMC_CMDAT_DMA_EN;
+ }
+ } else if (host->version >= JZ_MMC_JZ4780) {
+ writel(0, host->base + JZ_REG_MMC_DMAC);
+ }
writew(cmd->data->blksz, host->base + JZ_REG_MMC_BLKLEN);
writew(cmd->data->blocks, host->base + JZ_REG_MMC_NOB);
@@ -743,7 +805,7 @@ static irqreturn_t jz_mmc_irq_worker(int irq, void *devid)
host->state = JZ4740_MMC_STATE_SEND_STOP;
break;
}
- writew(JZ_MMC_IRQ_DATA_TRAN_DONE, host->base + JZ_REG_MMC_IREG);
+ host->write_irq_reg(host, JZ_MMC_IRQ_DATA_TRAN_DONE);
case JZ4740_MMC_STATE_SEND_STOP:
if (!req->stop)
@@ -773,9 +835,10 @@ static irqreturn_t jz_mmc_irq(int irq, void *devid)
{
struct jz4740_mmc_host *host = devid;
struct mmc_command *cmd = host->cmd;
- uint16_t irq_reg, status, tmp;
+ uint32_t irq_reg, status, tmp;
- irq_reg = readw(host->base + JZ_REG_MMC_IREG);
+ status = readl(host->base + JZ_REG_MMC_STATUS);
+ irq_reg = host->read_irq_reg(host);
tmp = irq_reg;
irq_reg &= ~host->irq_mask;
@@ -784,10 +847,10 @@ static irqreturn_t jz_mmc_irq(int irq, void *devid)
JZ_MMC_IRQ_PRG_DONE | JZ_MMC_IRQ_DATA_TRAN_DONE);
if (tmp != irq_reg)
- writew(tmp & ~irq_reg, host->base + JZ_REG_MMC_IREG);
+ host->write_irq_reg(host, tmp & ~irq_reg);
if (irq_reg & JZ_MMC_IRQ_SDIO) {
- writew(JZ_MMC_IRQ_SDIO, host->base + JZ_REG_MMC_IREG);
+ host->write_irq_reg(host, JZ_MMC_IRQ_SDIO);
mmc_signal_sdio_irq(host->mmc);
irq_reg &= ~JZ_MMC_IRQ_SDIO;
}
@@ -796,8 +859,6 @@ static irqreturn_t jz_mmc_irq(int irq, void *devid)
if (test_and_clear_bit(0, &host->waiting)) {
del_timer(&host->timeout_timer);
- status = readl(host->base + JZ_REG_MMC_STATUS);
-
if (status & JZ_MMC_STATUS_TIMEOUT_RES) {
cmd->error = -ETIMEDOUT;
} else if (status & JZ_MMC_STATUS_CRC_RES_ERR) {
@@ -810,7 +871,7 @@ static irqreturn_t jz_mmc_irq(int irq, void *devid)
}
jz4740_mmc_set_irq_enabled(host, irq_reg, false);
- writew(irq_reg, host->base + JZ_REG_MMC_IREG);
+ host->write_irq_reg(host, irq_reg);
return IRQ_WAKE_THREAD;
}
@@ -844,9 +905,7 @@ static void jz4740_mmc_request(struct mmc_host *mmc, struct mmc_request *req)
host->req = req;
- writew(0xffff, host->base + JZ_REG_MMC_IREG);
-
- writew(JZ_MMC_IRQ_END_CMD_RES, host->base + JZ_REG_MMC_IREG);
+ host->write_irq_reg(host, ~0);
jz4740_mmc_set_irq_enabled(host, JZ_MMC_IRQ_END_CMD_RES, true);
host->state = JZ4740_MMC_STATE_READ_RESPONSE;
@@ -973,6 +1032,7 @@ static void jz4740_mmc_free_gpios(struct platform_device *pdev)
static const struct of_device_id jz4740_mmc_of_match[] = {
{ .compatible = "ingenic,jz4740-mmc", .data = (void *) JZ_MMC_JZ4740 },
+ { .compatible = "ingenic,jz4780-mmc", .data = (void *) JZ_MMC_JZ4780 },
{},
};
MODULE_DEVICE_TABLE(of, jz4740_mmc_of_match);
@@ -1017,6 +1077,19 @@ static int jz4740_mmc_probe(struct platform_device* pdev)
goto err_free_host;
}
+ if (host->version >= JZ_MMC_JZ4780) {
+ host->write_irq_reg = jz4780_mmc_write_irq_reg;
+ host->read_irq_reg = jz4780_mmc_read_irq_reg;
+ } else {
+ host->write_irq_reg = jz4740_mmc_write_irq_reg;
+ host->read_irq_reg = jz4740_mmc_read_irq_reg;
+ }
+
+ if (host->version >= JZ_MMC_JZ4750)
+ host->write_irq_mask = jz4750_mmc_write_irq_mask;
+ else
+ host->write_irq_mask = jz4740_mmc_write_irq_mask;
+
host->irq = platform_get_irq(pdev, 0);
if (host->irq < 0) {
ret = host->irq;
@@ -1055,7 +1128,7 @@ static int jz4740_mmc_probe(struct platform_device* pdev)
host->mmc = mmc;
host->pdev = pdev;
spin_lock_init(&host->lock);
- host->irq_mask = 0xffff;
+ host->irq_mask = ~0;
jz4740_mmc_reset(host);
--
2.16.2
^ permalink raw reply related [flat|nested] 38+ messages in thread
* Re: [PATCH 08/14] mmc: jz4740: Add support for the JZ4780,
2018-03-09 15:12 ` [PATCH 08/14] mmc: jz4740: Add support for the JZ4780 Ezequiel Garcia
@ 2018-03-09 17:51 ` Paul Cercueil
2018-03-09 22:31 ` your mail James Hogan
0 siblings, 1 reply; 38+ messages in thread
From: Paul Cercueil @ 2018-03-09 17:51 UTC (permalink / raw)
To: Ezequiel Garcia
Cc: Ulf Hansson, linux-mmc, linux-mips, James Hogan, Alex Smith
Hi,
Le 2018-03-09 16:12, Ezequiel Garcia a écrit :
> From: Alex Smith <alex.smith@imgtec.com>
>
> Add support for the JZ4780 MMC controller to the jz47xx_mmc driver.
> There
> are a few minor differences from the 4740 to the 4780 that need to be
> handled, but otherwise the controllers behave the same. The IREG and
> IMASK
> registers are expanded to 32 bits. Additionally, some error conditions
> are
> now reported in both STATUS and IREG. Writing IREG before reading
> STATUS
> causes the bits in STATUS to be cleared, so STATUS must be read first
> to
> ensure we see and report error conditions correctly.
>
> Signed-off-by: Alex Smith <alex.smith@imgtec.com>
> Signed-off-by: Paul Cercueil <paul@crapouillou.net>
> [Ezequiel: rebase and introduce register accessors]
> Signed-off-by: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
> ---
> drivers/mmc/host/Kconfig | 2 +-
> drivers/mmc/host/jz4740_mmc.c | 111
> ++++++++++++++++++++++++++++++++++--------
> 2 files changed, 93 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
> index 620c2d90a646..7dd5169a2dfb 100644
> --- a/drivers/mmc/host/Kconfig
> +++ b/drivers/mmc/host/Kconfig
> @@ -767,7 +767,7 @@ config MMC_SH_MMCIF
>
> config MMC_JZ4740
> tristate "JZ4740 SD/Multimedia Card Interface support"
> - depends on MACH_JZ4740
> + depends on MACH_JZ4740 || MACH_JZ4780
> help
> This selects support for the SD/MMC controller on Ingenic JZ4740
> SoCs.
> diff --git a/drivers/mmc/host/jz4740_mmc.c
> b/drivers/mmc/host/jz4740_mmc.c
> index 7d4dcce76cd8..bb1b9114ef53 100644
> --- a/drivers/mmc/host/jz4740_mmc.c
> +++ b/drivers/mmc/host/jz4740_mmc.c
> @@ -1,5 +1,7 @@
> /*
> * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
> + * Copyright (C) 2013, Imagination Technologies
> + *
> * JZ4740 SD/MMC controller driver
> *
> * This program is free software; you can redistribute it and/or
> modify it
> @@ -52,6 +54,7 @@
> #define JZ_REG_MMC_RESP_FIFO 0x34
> #define JZ_REG_MMC_RXFIFO 0x38
> #define JZ_REG_MMC_TXFIFO 0x3C
> +#define JZ_REG_MMC_DMAC 0x44
>
> #define JZ_MMC_STRPCL_EXIT_MULTIPLE BIT(7)
> #define JZ_MMC_STRPCL_EXIT_TRANSFER BIT(6)
> @@ -105,11 +108,15 @@
> #define JZ_MMC_IRQ_PRG_DONE BIT(1)
> #define JZ_MMC_IRQ_DATA_TRAN_DONE BIT(0)
>
> +#define JZ_MMC_DMAC_DMA_SEL BIT(1)
> +#define JZ_MMC_DMAC_DMA_EN BIT(0)
>
> #define JZ_MMC_CLK_RATE 24000000
>
> enum jz4740_mmc_version {
> JZ_MMC_JZ4740,
> + JZ_MMC_JZ4750,
> + JZ_MMC_JZ4780,
> };
>
> enum jz4740_mmc_state {
> @@ -144,7 +151,7 @@ struct jz4740_mmc_host {
>
> uint32_t cmdat;
>
> - uint16_t irq_mask;
> + uint32_t irq_mask;
>
> spinlock_t lock;
>
> @@ -164,8 +171,46 @@ struct jz4740_mmc_host {
> * trigger is when data words in MSC_TXFIFO is < 8.
> */
> #define JZ4740_MMC_FIFO_HALF_SIZE 8
> +
> + void (*write_irq_mask)(struct jz4740_mmc_host *host, uint32_t val);
> + void (*write_irq_reg)(struct jz4740_mmc_host *host, uint32_t val);
> + uint32_t (*read_irq_reg)(struct jz4740_mmc_host *host);
> };
I'm not 100% fan about the callback idea, the original commit
(https://github.com/gcwnow/linux/commit/62472091) doesn't use them and
is
30 lines shorter.
I'm not terribly against either, so if nobody else bug on that, feel
free
to ignore my comment.
> +static void jz4750_mmc_write_irq_mask(struct jz4740_mmc_host *host,
> + uint32_t val)
> +{
> + return writel(val, host->base + JZ_REG_MMC_IMASK);
> +}
> +
> +static void jz4740_mmc_write_irq_mask(struct jz4740_mmc_host *host,
> + uint32_t val)
> +{
> + return writew(val, host->base + JZ_REG_MMC_IMASK);
> +}
> +
> +static void jz4740_mmc_write_irq_reg(struct jz4740_mmc_host *host,
> + uint32_t val)
> +{
> + return writew(val, host->base + JZ_REG_MMC_IREG);
> +}
> +
> +static uint32_t jz4740_mmc_read_irq_reg(struct jz4740_mmc_host *host)
> +{
> + return readw(host->base + JZ_REG_MMC_IREG);
> +}
> +
> +static void jz4780_mmc_write_irq_reg(struct jz4740_mmc_host *host,
> uint32_t val)
> +{
> + return writel(val, host->base + JZ_REG_MMC_IREG);
> +}
> +
> +/* In the 4780 onwards, IREG is expanded to 32 bits. */
> +static uint32_t jz4780_mmc_read_irq_reg(struct jz4740_mmc_host *host)
> +{
> + return readl(host->base + JZ_REG_MMC_IREG);
> +}
> +
>
> /*----------------------------------------------------------------------------*/
> /* DMA infrastructure */
>
> @@ -371,7 +416,7 @@ static void jz4740_mmc_set_irq_enabled(struct
> jz4740_mmc_host *host,
> host->irq_mask |= irq;
> spin_unlock_irqrestore(&host->lock, flags);
>
> - writew(host->irq_mask, host->base + JZ_REG_MMC_IMASK);
> + host->write_irq_mask(host, host->irq_mask);
> }
>
> static void jz4740_mmc_clock_enable(struct jz4740_mmc_host *host,
> @@ -422,10 +467,10 @@ static unsigned int jz4740_mmc_poll_irq(struct
> jz4740_mmc_host *host,
> unsigned int irq)
> {
> unsigned int timeout = 0x800;
> - uint16_t status;
> + uint32_t status;
>
> do {
> - status = readw(host->base + JZ_REG_MMC_IREG);
> + status = host->read_irq_reg(host);
> } while (!(status & irq) && --timeout);
>
> if (timeout == 0) {
> @@ -525,7 +570,7 @@ static bool jz4740_mmc_read_data(struct
> jz4740_mmc_host *host,
> void __iomem *fifo_addr = host->base + JZ_REG_MMC_RXFIFO;
> uint32_t *buf;
> uint32_t d;
> - uint16_t status;
> + uint32_t status;
> size_t i, j;
> unsigned int timeout;
>
> @@ -661,8 +706,25 @@ static void jz4740_mmc_send_command(struct
> jz4740_mmc_host *host,
> cmdat |= JZ_MMC_CMDAT_DATA_EN;
> if (cmd->data->flags & MMC_DATA_WRITE)
> cmdat |= JZ_MMC_CMDAT_WRITE;
> - if (host->use_dma)
> - cmdat |= JZ_MMC_CMDAT_DMA_EN;
> + if (host->use_dma) {
> + /*
> + * The 4780's MMC controller has integrated DMA ability
> + * in addition to being able to use the external DMA
> + * controller. It moves DMA control bits to a separate
> + * register. The DMA_SEL bit chooses the external
> + * controller over the integrated one. Earlier SoCs
> + * can only use the external controller, and have a
> + * single DMA enable bit in CMDAT.
> + */
> + if (host->version >= JZ_MMC_JZ4780) {
> + writel(JZ_MMC_DMAC_DMA_EN | JZ_MMC_DMAC_DMA_SEL,
> + host->base + JZ_REG_MMC_DMAC);
> + } else {
> + cmdat |= JZ_MMC_CMDAT_DMA_EN;
> + }
> + } else if (host->version >= JZ_MMC_JZ4780) {
> + writel(0, host->base + JZ_REG_MMC_DMAC);
> + }
>
> writew(cmd->data->blksz, host->base + JZ_REG_MMC_BLKLEN);
> writew(cmd->data->blocks, host->base + JZ_REG_MMC_NOB);
> @@ -743,7 +805,7 @@ static irqreturn_t jz_mmc_irq_worker(int irq, void
> *devid)
> host->state = JZ4740_MMC_STATE_SEND_STOP;
> break;
> }
> - writew(JZ_MMC_IRQ_DATA_TRAN_DONE, host->base + JZ_REG_MMC_IREG);
> + host->write_irq_reg(host, JZ_MMC_IRQ_DATA_TRAN_DONE);
>
> case JZ4740_MMC_STATE_SEND_STOP:
> if (!req->stop)
> @@ -773,9 +835,10 @@ static irqreturn_t jz_mmc_irq(int irq, void
> *devid)
> {
> struct jz4740_mmc_host *host = devid;
> struct mmc_command *cmd = host->cmd;
> - uint16_t irq_reg, status, tmp;
> + uint32_t irq_reg, status, tmp;
>
> - irq_reg = readw(host->base + JZ_REG_MMC_IREG);
> + status = readl(host->base + JZ_REG_MMC_STATUS);
> + irq_reg = host->read_irq_reg(host);
>
> tmp = irq_reg;
> irq_reg &= ~host->irq_mask;
> @@ -784,10 +847,10 @@ static irqreturn_t jz_mmc_irq(int irq, void
> *devid)
> JZ_MMC_IRQ_PRG_DONE | JZ_MMC_IRQ_DATA_TRAN_DONE);
>
> if (tmp != irq_reg)
> - writew(tmp & ~irq_reg, host->base + JZ_REG_MMC_IREG);
> + host->write_irq_reg(host, tmp & ~irq_reg);
>
> if (irq_reg & JZ_MMC_IRQ_SDIO) {
> - writew(JZ_MMC_IRQ_SDIO, host->base + JZ_REG_MMC_IREG);
> + host->write_irq_reg(host, JZ_MMC_IRQ_SDIO);
> mmc_signal_sdio_irq(host->mmc);
> irq_reg &= ~JZ_MMC_IRQ_SDIO;
> }
> @@ -796,8 +859,6 @@ static irqreturn_t jz_mmc_irq(int irq, void *devid)
> if (test_and_clear_bit(0, &host->waiting)) {
> del_timer(&host->timeout_timer);
>
> - status = readl(host->base + JZ_REG_MMC_STATUS);
> -
> if (status & JZ_MMC_STATUS_TIMEOUT_RES) {
> cmd->error = -ETIMEDOUT;
> } else if (status & JZ_MMC_STATUS_CRC_RES_ERR) {
> @@ -810,7 +871,7 @@ static irqreturn_t jz_mmc_irq(int irq, void *devid)
> }
>
> jz4740_mmc_set_irq_enabled(host, irq_reg, false);
> - writew(irq_reg, host->base + JZ_REG_MMC_IREG);
> + host->write_irq_reg(host, irq_reg);
>
> return IRQ_WAKE_THREAD;
> }
> @@ -844,9 +905,7 @@ static void jz4740_mmc_request(struct mmc_host
> *mmc, struct mmc_request *req)
>
> host->req = req;
>
> - writew(0xffff, host->base + JZ_REG_MMC_IREG);
> -
> - writew(JZ_MMC_IRQ_END_CMD_RES, host->base + JZ_REG_MMC_IREG);
> + host->write_irq_reg(host, ~0);
> jz4740_mmc_set_irq_enabled(host, JZ_MMC_IRQ_END_CMD_RES, true);
>
> host->state = JZ4740_MMC_STATE_READ_RESPONSE;
> @@ -973,6 +1032,7 @@ static void jz4740_mmc_free_gpios(struct
> platform_device *pdev)
>
> static const struct of_device_id jz4740_mmc_of_match[] = {
> { .compatible = "ingenic,jz4740-mmc", .data = (void *) JZ_MMC_JZ4740
> },
> + { .compatible = "ingenic,jz4780-mmc", .data = (void *) JZ_MMC_JZ4780
> },
> {},
> };
> MODULE_DEVICE_TABLE(of, jz4740_mmc_of_match);
> @@ -1017,6 +1077,19 @@ static int jz4740_mmc_probe(struct
> platform_device* pdev)
> goto err_free_host;
> }
>
> + if (host->version >= JZ_MMC_JZ4780) {
> + host->write_irq_reg = jz4780_mmc_write_irq_reg;
> + host->read_irq_reg = jz4780_mmc_read_irq_reg;
> + } else {
> + host->write_irq_reg = jz4740_mmc_write_irq_reg;
> + host->read_irq_reg = jz4740_mmc_read_irq_reg;
> + }
> +
> + if (host->version >= JZ_MMC_JZ4750)
> + host->write_irq_mask = jz4750_mmc_write_irq_mask;
> + else
> + host->write_irq_mask = jz4740_mmc_write_irq_mask;
> +
> host->irq = platform_get_irq(pdev, 0);
> if (host->irq < 0) {
> ret = host->irq;
> @@ -1055,7 +1128,7 @@ static int jz4740_mmc_probe(struct
> platform_device* pdev)
> host->mmc = mmc;
> host->pdev = pdev;
> spin_lock_init(&host->lock);
> - host->irq_mask = 0xffff;
> + host->irq_mask = ~0;
>
> jz4740_mmc_reset(host);
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: your mail
2018-03-09 17:51 ` [PATCH 08/14] mmc: jz4740: Add support for the JZ4780, Paul Cercueil
@ 2018-03-09 22:31 ` James Hogan
2018-03-09 22:31 ` James Hogan
0 siblings, 1 reply; 38+ messages in thread
From: James Hogan @ 2018-03-09 22:31 UTC (permalink / raw)
To: Paul Cercueil
Cc: Ezequiel Garcia, Ulf Hansson, linux-mmc, linux-mips, Alex Smith
[-- Attachment #1: Type: text/plain, Size: 1023 bytes --]
On Fri, Mar 09, 2018 at 06:51:36PM +0100, Paul Cercueil wrote:
> Le 2018-03-09 16:12, Ezequiel Garcia a écrit :
> > @@ -164,8 +171,46 @@ struct jz4740_mmc_host {
> > * trigger is when data words in MSC_TXFIFO is < 8.
> > */
> > #define JZ4740_MMC_FIFO_HALF_SIZE 8
> > +
> > + void (*write_irq_mask)(struct jz4740_mmc_host *host, uint32_t val);
> > + void (*write_irq_reg)(struct jz4740_mmc_host *host, uint32_t val);
> > + uint32_t (*read_irq_reg)(struct jz4740_mmc_host *host);
> > };
>
> I'm not 100% fan about the callback idea, the original commit
> (https://github.com/gcwnow/linux/commit/62472091) doesn't use them and
> is
> 30 lines shorter.
>
> I'm not terribly against either, so if nobody else bug on that, feel
> free
> to ignore my comment.
I was thinking the same as Paul too to be honest. Unless there is a
measurable benefit to having callbacks, I think its cleaner and more
readable to stick to conditionals and normal abstractions where
appropriate.
Cheers
James
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: your mail
2018-03-09 22:31 ` your mail James Hogan
@ 2018-03-09 22:31 ` James Hogan
0 siblings, 0 replies; 38+ messages in thread
From: James Hogan @ 2018-03-09 22:31 UTC (permalink / raw)
To: Paul Cercueil
Cc: Ezequiel Garcia, Ulf Hansson, linux-mmc, linux-mips, Alex Smith
[-- Attachment #1: Type: text/plain, Size: 1023 bytes --]
On Fri, Mar 09, 2018 at 06:51:36PM +0100, Paul Cercueil wrote:
> Le 2018-03-09 16:12, Ezequiel Garcia a écrit :
> > @@ -164,8 +171,46 @@ struct jz4740_mmc_host {
> > * trigger is when data words in MSC_TXFIFO is < 8.
> > */
> > #define JZ4740_MMC_FIFO_HALF_SIZE 8
> > +
> > + void (*write_irq_mask)(struct jz4740_mmc_host *host, uint32_t val);
> > + void (*write_irq_reg)(struct jz4740_mmc_host *host, uint32_t val);
> > + uint32_t (*read_irq_reg)(struct jz4740_mmc_host *host);
> > };
>
> I'm not 100% fan about the callback idea, the original commit
> (https://github.com/gcwnow/linux/commit/62472091) doesn't use them and
> is
> 30 lines shorter.
>
> I'm not terribly against either, so if nobody else bug on that, feel
> free
> to ignore my comment.
I was thinking the same as Paul too to be honest. Unless there is a
measurable benefit to having callbacks, I think its cleaner and more
readable to stick to conditionals and normal abstractions where
appropriate.
Cheers
James
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 38+ messages in thread
* (no subject)
@ 2005-04-28 19:15 Bryan Althouse
2005-04-29 11:02 ` your mail Ralf Baechle
0 siblings, 1 reply; 38+ messages in thread
From: Bryan Althouse @ 2005-04-28 19:15 UTC (permalink / raw)
To: linux-mips; +Cc: TheNop
Hello,
I would like to use a 2.6.x kernel with my Yosemite/HalfDome board.
Somehow, I am unable to compile the kernel. I have tried the 2.6.10 kernel
trees from ftp.pmc-sierra.com and also the latest 2.6.12 snapshot from
linux-mips. I am using the 3.3.x cross compile tools from
ftp.pmc-sierra.com . The 2.4.x kernels from PMC compile fine.
In the case of 2.6.10 from ftp.pmc-sierra.com, my error looks like:
Make[3]: *** [drivers/char/agp/backend.o] Error 1
In the case of 2.6.12 from linux-mips, my error looks like:
drivers/net/titan_ge.c1950: error: 'titan_device_remove" undeclared
here (not in a function)
My compile process is like so:
make mrproper
make xconfig
make oldconfig
make ARCH=mips CROSS_COMPILE=/<tool_path>/mips64-linux-gnu- vmlinux
Could someone share their .config with me, or make some suggestions?
Thank you,
Bryan
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: your mail
2005-04-28 19:15 Bryan Althouse
@ 2005-04-29 11:02 ` Ralf Baechle
0 siblings, 0 replies; 38+ messages in thread
From: Ralf Baechle @ 2005-04-29 11:02 UTC (permalink / raw)
To: Bryan Althouse; +Cc: linux-mips, TheNop
On Thu, Apr 28, 2005 at 03:15:49PM -0400, Bryan Althouse wrote:
> I would like to use a 2.6.x kernel with my Yosemite/HalfDome board.
> Somehow, I am unable to compile the kernel. I have tried the 2.6.10 kernel
> trees from ftp.pmc-sierra.com and also the latest 2.6.12 snapshot from
> linux-mips. I am using the 3.3.x cross compile tools from
> ftp.pmc-sierra.com . The 2.4.x kernels from PMC compile fine.
>
> In the case of 2.6.10 from ftp.pmc-sierra.com, my error looks like:
> Make[3]: *** [drivers/char/agp/backend.o] Error 1
Configuring AGP support for a MIPS kernel is obviously nonsense. Disable
CONFIG_AGP.
> In the case of 2.6.12 from linux-mips, my error looks like:
> drivers/net/titan_ge.c1950: error: 'titan_device_remove" undeclared
> here (not in a function)
Whoops, a bug. The function indeed doesn't exist even though it should,
will fix that. You will hit this bug only if compiling the titan driver
as a module, so workaround set CONFIG_TITAN_GE=y. Which for the typical
titan-based device seems to be the preferable choice anyway.
Ralf
^ permalink raw reply [flat|nested] 38+ messages in thread
* RE: your mail
@ 2003-04-18 0:08 Dennis Castleman
0 siblings, 0 replies; 38+ messages in thread
From: Dennis Castleman @ 2003-04-18 0:08 UTC (permalink / raw)
To: 'Ralf Baechle', Dennis Castleman; +Cc: linux-mips
[-- Attachment #1: Type: text/plain, Size: 3089 bytes --]
Thanks Ralf
Looks like I made the correct call when I picked MIPS32 Kernel.
Look like some of my preformance issues are in Montavistas 2.95.3 toolchain,
it's generating code that looks like this
0000000000000000 <bitBufferCreate>:
0: 27bdffe0 addiu $sp,$sp,-32
4: afbf001c sw $ra,28($sp)
8: afb20018 sw $s2,24($sp)
c: afb10014 sw $s1,20($sp)
10: afb00010 sw $s0,16($sp)
14: 00809021 move $s2,$a0
18: 00a08021 move $s0,$a1
1c: 00c08821 move $s1,$a2
20: 24040001 li $a0,1
24: 24050010 li $a1,16
28: 3c020000 lui $v0,0x0
2c: 24420000 addiu $v0,$v0,0
but if I use the 2.95.3 toolchain I build myself it's
generating code that looks like this.
0000000000000000 <bitBufferCreate>:
0: 27bdffe0 addiu $sp,$sp,-32
4: afb20018 sw $s2,24($sp)
8: 00809021 move $s2,$a0
c: afb00010 sw $s0,16($sp)
10: 00a08021 move $s0,$a1
14: afb10014 sw $s1,20($sp)
18: 00c08821 move $s1,$a2
1c: 24040001 li $a0,1
20: 24050010 li $a1,16
24: 3c020000 lui $v0,0x0
28: 24420000 addiu $v0,$v0,0
Any idea whats up MV tool-chain.
Dennis
-----Original Message-----
From: Ralf Baechle [mailto:ralf@linux-mips.org]
Sent: Thursday, April 17, 2003 5:04 PM
To: Dennis Castleman
Cc: linux-mips@linux-mips.org
Subject: Re: your mail
On Thu, Apr 17, 2003 at 10:53:57AM -0700, Dennis Castleman wrote:
> Anybody know the performance differences I can expect using a MIPS 5K core
> @250 Mhz in 64bit mode versus 32bit mode?
As a rule of thumb - less performance. 64-bit code is typically larger
resulting in lower cache hit rate. And since performance optimization
these days is essentially equivalent to maximising the cache hit rate
going 64-bit usually means a performance drop due to the drastically
larger size of code and data.
On the positive side for 64-bit stuff there's the possibility to do
64-bit computations with just one instruction, move data with less
instructions, use twice as many double precission fp registers that are
offered by 64-bit ABIs and more calling sequences.
The first two paragraphs were sort of a generic statement regarding
32-bit vs. 64-bit software on MIPS processors and affect both kernel and
userspace. There's a few additional issues with the Linux kernel.
The 32-bit kernels requires all memory to be addressable through KSEG0
which limits it to at most 512MB; typically the limit is more like 256MB.
Memory above 512MB physical address can only be used as highmem. That's
fairly inefficient and requires alot of special care when writing new
kernel software. For processors that suffer from virtual aliases in
their data cache highmem currently is frighteningly inefficient - and
high memory pressure on lowmem doesn't help either. So from a certain
point on that's simply making a 64-bit kernel is simply the better
idea - even for running 32-bit software. That in particular applies
to very I/O intensive stuff.
In short - the right choice is a tradeoff between the hardware platform
and the application's requirements. Choose wrong and you'll curse
loudly :-)
Ralf
[-- Attachment #2: Type: text/html, Size: 5525 bytes --]
^ permalink raw reply [flat|nested] 38+ messages in thread
* (no subject)
@ 2003-04-17 17:53 Dennis Castleman
2003-04-17 18:17 ` your mail Jun Sun
2003-04-18 0:03 ` Ralf Baechle
0 siblings, 2 replies; 38+ messages in thread
From: Dennis Castleman @ 2003-04-17 17:53 UTC (permalink / raw)
To: linux-mips
[-- Attachment #1: Type: text/plain, Size: 132 bytes --]
ALL
Anybody know the performance differences I can expect using a MIPS 5K core
@250 Mhz in 64bit mode versus 32bit mode?
Dennis
[-- Attachment #2: Type: text/html, Size: 539 bytes --]
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: your mail
2003-04-17 17:53 Dennis Castleman
@ 2003-04-17 18:17 ` Jun Sun
2003-04-17 20:15 ` Greg Lindahl
2003-04-18 0:03 ` Ralf Baechle
1 sibling, 1 reply; 38+ messages in thread
From: Jun Sun @ 2003-04-17 18:17 UTC (permalink / raw)
To: Dennis Castleman; +Cc: linux-mips, jsun
On Thu, Apr 17, 2003 at 10:53:57AM -0700, Dennis Castleman wrote:
> ALL
>
> Anybody know the performance differences I can expect using a MIPS 5K core
> @250 Mhz in 64bit mode versus 32bit mode?
>
It really depends on the applications. The biggest gain from 64bit,
other than the obviously bigger address space, is 64bit data
manipulation. A single 64bit instruction (add/sub/...) is carried
out by several instructions in 32bit.
If your apps are heavy on 64bit operations, then you gain.
Otherwise I suspect no performance gain or even possibly a little
worse performance due more stress on cache/memory subsystems.
I am sure others with more 64bit experience probably have more
to say. :)
Jun
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: your mail
2003-04-17 18:17 ` your mail Jun Sun
@ 2003-04-17 20:15 ` Greg Lindahl
0 siblings, 0 replies; 38+ messages in thread
From: Greg Lindahl @ 2003-04-17 20:15 UTC (permalink / raw)
To: linux-mips
On Thu, Apr 17, 2003 at 11:17:10AM -0700, Jun Sun wrote:
> It really depends on the applications. The biggest gain from 64bit,
> other than the obviously bigger address space, is 64bit data
> manipulation. A single 64bit instruction (add/sub/...) is carried
> out by several instructions in 32bit.
A big gain is the increased # of registers and better calling
sequence. Everyone sees that, not just people who want to use 64-bit
integers. At the moment you need to run the 64-bit kernel -- and the
new binutils & glibc -- in order to get n32 programs to work.
-- greg
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: your mail
2003-04-17 17:53 Dennis Castleman
2003-04-17 18:17 ` your mail Jun Sun
@ 2003-04-18 0:03 ` Ralf Baechle
1 sibling, 0 replies; 38+ messages in thread
From: Ralf Baechle @ 2003-04-18 0:03 UTC (permalink / raw)
To: Dennis Castleman; +Cc: linux-mips
On Thu, Apr 17, 2003 at 10:53:57AM -0700, Dennis Castleman wrote:
> Anybody know the performance differences I can expect using a MIPS 5K core
> @250 Mhz in 64bit mode versus 32bit mode?
As a rule of thumb - less performance. 64-bit code is typically larger
resulting in lower cache hit rate. And since performance optimization
these days is essentially equivalent to maximising the cache hit rate
going 64-bit usually means a performance drop due to the drastically
larger size of code and data.
On the positive side for 64-bit stuff there's the possibility to do
64-bit computations with just one instruction, move data with less
instructions, use twice as many double precission fp registers that are
offered by 64-bit ABIs and more calling sequences.
The first two paragraphs were sort of a generic statement regarding
32-bit vs. 64-bit software on MIPS processors and affect both kernel and
userspace. There's a few additional issues with the Linux kernel.
The 32-bit kernels requires all memory to be addressable through KSEG0
which limits it to at most 512MB; typically the limit is more like 256MB.
Memory above 512MB physical address can only be used as highmem. That's
fairly inefficient and requires alot of special care when writing new
kernel software. For processors that suffer from virtual aliases in
their data cache highmem currently is frighteningly inefficient - and
high memory pressure on lowmem doesn't help either. So from a certain
point on that's simply making a 64-bit kernel is simply the better
idea - even for running 32-bit software. That in particular applies
to very I/O intensive stuff.
In short - the right choice is a tradeoff between the hardware platform
and the application's requirements. Choose wrong and you'll curse
loudly :-)
Ralf
^ permalink raw reply [flat|nested] 38+ messages in thread
* (no subject)
@ 2003-03-29 6:54 Avinash S.
2003-03-29 7:25 ` your mail Thiemo Seufer
0 siblings, 1 reply; 38+ messages in thread
From: Avinash S. @ 2003-03-29 6:54 UTC (permalink / raw)
To: linux
Hello,
Im trying to build a kernel config for a big endian IDT79S334 board. I
have sucessfully mangaged to get a vmlinux image using Embedix tools for
little endian but am having problems with big endian configs. I am using
binutils version 2.8. I get an error when i reaches irq.c saying:
Unknown ISA level
Unknown opcode 'clz'
im using a mips-linux-gcc from egcs pacakge(1.1.2-4). Does anyone know
how to solve this problem or where can i get a mips-linux-gcc that
supports the opcode.
Thanks in advance
Avinash
pS: here is the make dump that shows the error.
--------------------------------------------------------------------------
make[1]: Entering directory
`/home1/ixe2424/proj/ixe2424/IDT/linux/arch/mips/rc32300/79S334'
make all_targets
make[2]: Entering directory
`/home1/ixe2424/proj/ixe2424/IDT/linux/arch/mips/rc32300/79S334'
mips-linux-gcc -I /home1/ixe2424/proj/ixe2424/IDT/linux/include/asm/gcc -
D__KERNEL__ -I/home1/ixe2424/proj/ixe2424/IDT/linux/include -Wall -
Wstrict-prototypes -Wno-trigraphs -O2 -fomit-frame-pointer -fno-common -
fno-strict-aliasing -G 0 -mno-abicalls -fno-pic -mcpu=r4600 -mips2 -Wa,--
trap -pipe -DKBUILD_BASENAME=irq -c -o irq.o irq.c
{standard input}: Assembler messages:
{standard input}:1076: Error: unknown ISA level
{standard input}:1077: Error: unrecognized opcode `clz'
{standard input}:1116: Error: unknown ISA level
{standard input}:1117: Error: unrecognized opcode `clz'
{standard input}:1193: Error: unknown ISA level
{standard input}:1194: Error: unrecognized opcode `clz'
make[2]: *** [irq.o] Error 1
make[2]: Leaving directory
`/home1/ixe2424/proj/ixe2424/IDT/linux/arch/mips/rc32300/79S334'
make[1]: *** [first_rule] Error 2
make[1]: Leaving directory
`/home1/ixe2424/proj/ixe2424/IDT/linux/arch/mips/rc32300/79S334'
make: *** [_dir_arch/mips/rc32300/79S334] Error 2
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: your mail
2003-03-29 6:54 Avinash S.
@ 2003-03-29 7:25 ` Thiemo Seufer
0 siblings, 0 replies; 38+ messages in thread
From: Thiemo Seufer @ 2003-03-29 7:25 UTC (permalink / raw)
To: Avinash S.; +Cc: linux
Avinash S. wrote:
> Hello,
>
> Im trying to build a kernel config for a big endian IDT79S334 board. I
> have sucessfully mangaged to get a vmlinux image using Embedix tools for
> little endian but am having problems with big endian configs. I am using
> binutils version 2.8. I get an error when i reaches irq.c saying:
^^^
That's _very_ old.
> Unknown ISA level
> Unknown opcode 'clz'
>
> im using a mips-linux-gcc from egcs pacakge(1.1.2-4). Does anyone know
> how to solve this problem or where can i get a mips-linux-gcc that
> supports the opcode.
It's the assembler, not the compiler. Upgrade binutils.
Thiemo
^ permalink raw reply [flat|nested] 38+ messages in thread
* (no subject)
@ 2002-10-26 19:48 Zajerko-McKee, Nick
2002-10-26 20:08 ` your mail Daniel Jacobowitz
2002-10-26 20:32 ` Greg Lindahl
0 siblings, 2 replies; 38+ messages in thread
From: Zajerko-McKee, Nick @ 2002-10-26 19:48 UTC (permalink / raw)
To: 'linux-mips@linux-mips.org'
Hi,
I'm porting some code from x86 to mips(32) and noticed that in
include/asm-mips/siginfo.h differs from include/asm-i386/siginfo.h in the
order of elements of the sigchld structure. Was this an oversight or a
design decision? I would think that it would be desirable to be almost the
same as the x86 for userland ease of portability...
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: your mail
2002-10-26 19:48 Zajerko-McKee, Nick
@ 2002-10-26 20:08 ` Daniel Jacobowitz
2002-10-26 20:32 ` Greg Lindahl
1 sibling, 0 replies; 38+ messages in thread
From: Daniel Jacobowitz @ 2002-10-26 20:08 UTC (permalink / raw)
To: Zajerko-McKee, Nick; +Cc: 'linux-mips@linux-mips.org'
On Sat, Oct 26, 2002 at 03:48:27PM -0400, Zajerko-McKee, Nick wrote:
> Hi,
>
> I'm porting some code from x86 to mips(32) and noticed that in
> include/asm-mips/siginfo.h differs from include/asm-i386/siginfo.h in the
> order of elements of the sigchld structure. Was this an oversight or a
> design decision? I would think that it would be desirable to be almost the
> same as the x86 for userland ease of portability...
It's probably for compatibility with that other MIPS operating system -
IRIX.
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: your mail
2002-10-26 19:48 Zajerko-McKee, Nick
2002-10-26 20:08 ` your mail Daniel Jacobowitz
@ 2002-10-26 20:32 ` Greg Lindahl
1 sibling, 0 replies; 38+ messages in thread
From: Greg Lindahl @ 2002-10-26 20:32 UTC (permalink / raw)
To: 'linux-mips@linux-mips.org'
On Sat, Oct 26, 2002 at 03:48:27PM -0400, Zajerko-McKee, Nick wrote:
> I'm porting some code from x86 to mips(32) and noticed that in
> include/asm-mips/siginfo.h differs from include/asm-i386/siginfo.h in the
> order of elements of the sigchld structure. Was this an oversight or a
> design decision? I would think that it would be desirable to be almost the
> same as the x86 for userland ease of portability...
User programs normally get recompiled, so anything using the proper
includes IS portable.
The issue only appears if you are using binary translation of x86
programs on mips. For example, this is one:
http://www.transitives.com/products.htm
For this, you need to write a system call translation layer which
rearranges things appropriately. An existing example is the o32 layer
in mips64, and soon the n32 layer in mips64.
-- greg
^ permalink raw reply [flat|nested] 38+ messages in thread
* (no subject)
@ 2001-10-03 14:28 Marian Kafadarov
2001-10-03 15:52 ` your mail Martin Schulze
0 siblings, 1 reply; 38+ messages in thread
From: Marian Kafadarov @ 2001-10-03 14:28 UTC (permalink / raw)
To: linux-mips
Hello,
We have DEC station 5000 / 240
From were we can download Linux distribution and documentation for it and
what we can do on it.
Best regards: Marian Kafadarov
Technical
university of Plovdiv
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: your mail
2001-10-03 14:28 Marian Kafadarov
@ 2001-10-03 15:52 ` Martin Schulze
0 siblings, 0 replies; 38+ messages in thread
From: Martin Schulze @ 2001-10-03 15:52 UTC (permalink / raw)
To: Marian Kafadarov; +Cc: linux-mips
Marian Kafadarov wrote:
> Hello,
> We have DEC station 5000 / 240
> From were we can download Linux distribution and documentation for it and
> what we can do on it.
You could wait until we have finished boot-floppies for this machine
(1-3 weeks) or bootstrap from scratch by using a kernel and a Debian
base system. Both is available, Karsten can also provide a correct
2.4.x kernel.
I'd rather like to ask you to wait a couple of days/weeks until
boot-floppies are available for this machine and you can use the
regular Debian installation process which will be less painful
than the other. If you do so, please come back to us in some
days/weeks to find out if things are ready already.
Regards,
Joey
--
All language designers are arrogant. Goes with the territory...
-- Larry Wall
^ permalink raw reply [flat|nested] 38+ messages in thread
[parent not found: <5.0.0.25.0.20010404172906.00a4bce8@vmspop.isc.rit.edu>]
* Re: your mail
[not found] <5.0.0.25.0.20010404172906.00a4bce8@vmspop.isc.rit.edu>
@ 2001-04-04 21:37 ` Matthew Fredrickson
2001-04-05 5:08 ` Ralf Baechle
0 siblings, 1 reply; 38+ messages in thread
From: Matthew Fredrickson @ 2001-04-04 21:37 UTC (permalink / raw)
To: jsc6233, linux-mips
[-- Attachment #1: Type: text/plain, Size: 1216 bytes --]
On Wed, Apr 04, 2001 at 05:29:54PM -0700, jsc6233@ritvax.isc.rit.edu wrote:
>
> hello,
> Yeah i am trying to compile it while running Irix 6.5. Once i get it all
> working I was going to boot into it. Does that make sense?
> james
<g>No offense, but not really. Actually, you'll probably need to start
off by setting up the x86-mips cross compilers on an x86 linux machine of
yours and booting the kernel via tftp over the network to get started. I
think most of this is covered in the FAQ on the site. Anyway, I don't
think it's _ever_ been supported to compile up the kernel in IRIX anyway,
so your kind of out of luck for that. On a side note, you probably want
to stop by freeware.sgi.com and upgrade your gcc from 2.7 to the latest
(2.95.3 I think). Might even try downloading some pre3.0 stuff and try
that out. Back to topic: Read EVERYTHING you can on the linux-mips sgi
site before asking a question here; if you don't, that's a very good way
to get kindly (and a lot of times unkindly) pointed to the FAQ. Hope this
helps.
--
Matthew Fredrickson AIM MatthewFredricks
ICQ 13923212 matt@NOSPAMfredricknet.net
http://www.fredricknet.net/~matt/
"Everything is relative"
[-- Attachment #2: Type: application/pgp-signature, Size: 232 bytes --]
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: your mail
2001-04-04 21:37 ` Matthew Fredrickson
@ 2001-04-05 5:08 ` Ralf Baechle
0 siblings, 0 replies; 38+ messages in thread
From: Ralf Baechle @ 2001-04-05 5:08 UTC (permalink / raw)
To: Matthew Fredrickson; +Cc: jsc6233, linux-mips
On Wed, Apr 04, 2001 at 04:37:47PM -0500, Matthew Fredrickson wrote:
> > hello,
> > Yeah i am trying to compile it while running Irix 6.5. Once i get it all
> > working I was going to boot into it. Does that make sense?
> > james
>
> <g>No offense, but not really. Actually, you'll probably need to start
> off by setting up the x86-mips cross compilers on an x86 linux machine of
> yours and booting the kernel via tftp over the network to get started. I
> think most of this is covered in the FAQ on the site. Anyway, I don't
> think it's _ever_ been supported to compile up the kernel in IRIX anyway,
> so your kind of out of luck for that.
You obvious didn't even check. I assure you that I rarely compile a MIPS
kernel under Linux so if that works, it's coincidental. Crosscompiling
on IRIX works just fine.
Ralf
^ permalink raw reply [flat|nested] 38+ messages in thread
* (no subject)
@ 2001-02-15 0:27 Deepa Suresh
2001-02-15 11:03 ` your mail Geert Uytterhoeven
0 siblings, 1 reply; 38+ messages in thread
From: Deepa Suresh @ 2001-02-15 0:27 UTC (permalink / raw)
To: linux-mips; +Cc: deepa.suresh
Hello,
We have a QED based MIPs processor, running Linux 2.4-test6.
We use our own graphics card.
We want to get X/display up on this board. WE have a frame buffer driver
written
for the same card running on x86 Linux version and running X using
XFBDev server.
I want to know if we can reuse the same driver for mips also?
In the case of i386 Linux, fbcon.c and fbmem.c do most of the
processing before giving control to the corresponding graphics card.
In mips port can we use the same fbcon.c and fbmem.c functionality
with our graphics driver. Is this enough for X to come up
without any problems. (i have seen sgi using newport_con , can we use
fb_con itself instead , what are the problems?)
I did see in the mailing list, someone mentioning using ATI graphics
card with the same hardware and running X. How was the frame buffer
driver modified?
Any help on this would be appreciated.
Thanks & Rgds
deepa
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: your mail
2001-02-15 0:27 Deepa Suresh
@ 2001-02-15 11:03 ` Geert Uytterhoeven
0 siblings, 0 replies; 38+ messages in thread
From: Geert Uytterhoeven @ 2001-02-15 11:03 UTC (permalink / raw)
To: Deepa Suresh; +Cc: linux-mips
On Wed, 14 Feb 2001, Deepa Suresh wrote:
> We have a QED based MIPs processor, running Linux 2.4-test6.
> We use our own graphics card.
> We want to get X/display up on this board. WE have a frame buffer driver
> written
> for the same card running on x86 Linux version and running X using
> XFBDev server.
Does the frame buffer driver you wrote for x86 Linux relies on the card being
initialised by the video BIOS on the card? If not, it'll work out-of-the-box.
If yes, you'll have to make sure a similar initialization is done on the MIPS
platform.
> I want to know if we can reuse the same driver for mips also?
> In the case of i386 Linux, fbcon.c and fbmem.c do most of the
> processing before giving control to the corresponding graphics card.
>
> In mips port can we use the same fbcon.c and fbmem.c functionality
> with our graphics driver. Is this enough for X to come up
> without any problems. (i have seen sgi using newport_con , can we use
> fb_con itself instead , what are the problems?)
Fbmem and fbcon should work fine. They are not architecture specific.
And if these work, XF{68,86}_FBDev should work as well.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven ------------- Sony Software Development Center Europe (SDCE)
Geert.Uytterhoeven@sonycom.com ------------------- Sint-Stevens-Woluwestraat 55
Voice +32-2-7248626 Fax +32-2-7262686 ---------------- B-1130 Brussels, Belgium
^ permalink raw reply [flat|nested] 38+ messages in thread
* (no subject)
@ 2001-01-04 1:36 John Van Horne
2001-01-04 15:36 ` your mail Ralf Baechle
0 siblings, 1 reply; 38+ messages in thread
From: John Van Horne @ 2001-01-04 1:36 UTC (permalink / raw)
To: 'linux-mips@oss.sgi.com'; +Cc: 'wesolows@foobazco.org'
[-- Attachment #1: Type: text/plain, Size: 1546 bytes --]
Hello,
I downloaded cross-all-001027.tar from
oss.sgi.com/pub/linux/mips/mips-linux/simple/crossdev,
built it on my ix86 Linux box, and have tried to use it on our Linux
application and Linux kernel.
I'm getting errors which we didn't see when we were using
binutils-mips-linux-2.8.1 and
egcs-mips-linux-1.0.3a.
First, while the kernel builds just fine, when we use objcopy to convert the
elf image into a binary
image which we can download to our target, objcopy fails with warnings
saying that it is writing
sections to huge (i.e. negative) file offsets. When I use objdump to analyze
the kernel image,
I see that our start address of 0x80102584 has been turned into
0xffffffff80102584. I'm thinking that
I need to tell ld something to stop it from doing this. Any ideas?
Second, the way we build our application, we first create a partially linked
image, with the -r flag. Then
we run ld on this (and an additional object file). When we do this with the
tools from cross-all-001027
we get the following error on the second link step:
mips-linux-ld: BFD internal error, aborting at
/homes/local/mips-cross/crossdev-build/src/binutils-001027/bfd/elf32-mips.c
line 6942 in _bfd_mips_elf_relocate_section
mips-linux-ld: Please report this bug.
Actually, on the application we didn't get this far using
binutils-mips-linux-2.8.1 and egcs-mips-linux-1.0.3a,
so I have nothing to compare it to. I'm not sure if this is a bug or if I
should be passing some flags to gcc or ld.
Any help you can provide would be appreciated.
Thanks,
-John
[-- Attachment #2: Type: text/html, Size: 2640 bytes --]
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: your mail
2001-01-04 1:36 John Van Horne
@ 2001-01-04 15:36 ` Ralf Baechle
2001-01-04 16:22 ` Maciej W. Rozycki
0 siblings, 1 reply; 38+ messages in thread
From: Ralf Baechle @ 2001-01-04 15:36 UTC (permalink / raw)
To: John Van Horne
Cc: 'linux-mips@oss.sgi.com', 'wesolows@foobazco.org'
On Wed, Jan 03, 2001 at 05:36:44PM -0800, John Van Horne wrote:
> First, while the kernel builds just fine, when we use objcopy to convert the
> elf image into a binary
> image which we can download to our target, objcopy fails with warnings
> saying that it is writing
> sections to huge (i.e. negative) file offsets. When I use objdump to analyze
> the kernel image,
> I see that our start address of 0x80102584 has been turned into
> 0xffffffff80102584. I'm thinking that
> I need to tell ld something to stop it from doing this. Any ideas?
That's be ok. 32-bit MIPS addresses are sign-extended into 64-bit addresses.
Older binutils used to zero-extend addresses which was broken. So what
you observe is actually the sympthom of a bug that got fixed.
> Second, the way we build our application, we first create a partially linked
> image, with the -r flag. Then
> we run ld on this (and an additional object file). When we do this with the
> tools from cross-all-001027
> we get the following error on the second link step:
>
> mips-linux-ld: BFD internal error, aborting at
> /homes/local/mips-cross/crossdev-build/src/binutils-001027/bfd/elf32-mips.c
> line 6942 in _bfd_mips_elf_relocate_section
>
> mips-linux-ld: Please report this bug.
Not good ... Two possibilities.
- it's fairly easy to make ld die in funny ways by feeding it with nonsense
options, linker scripts or similar.
- it's really a bug.
Assuming it's really a bug, can you extract a small test case that
demonstrate this bug?
> Actually, on the application we didn't get this far using
> binutils-mips-linux-2.8.1 and egcs-mips-linux-1.0.3a,
> so I have nothing to compare it to. I'm not sure if this is a bug or if I
> should be passing some flags to gcc or ld.
It may well be a bug; especially -r is used relativly rarely so the code
isn't getting excercised too well. I'd like to see it get fixed in the
current linker, though.
Ralf
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: your mail
2001-01-04 15:36 ` your mail Ralf Baechle
@ 2001-01-04 16:22 ` Maciej W. Rozycki
2001-01-04 16:40 ` Joe deBlaquiere
0 siblings, 1 reply; 38+ messages in thread
From: Maciej W. Rozycki @ 2001-01-04 16:22 UTC (permalink / raw)
To: Ralf Baechle
Cc: John Van Horne, 'linux-mips@oss.sgi.com',
'wesolows@foobazco.org'
On Thu, 4 Jan 2001, Ralf Baechle wrote:
> > I see that our start address of 0x80102584 has been turned into
> > 0xffffffff80102584. I'm thinking that
> > I need to tell ld something to stop it from doing this. Any ideas?
>
> That's be ok. 32-bit MIPS addresses are sign-extended into 64-bit addresses.
> Older binutils used to zero-extend addresses which was broken. So what
> you observe is actually the sympthom of a bug that got fixed.
I'm not sure that's the best solution, I'm afraid. For elf32-mips
addresses should be 32-bit and not 64-bit. It would be consistent with
other 32-bit platforms, it would make interoperability easier (ksymoops
cannot make use of System.map to grok kernel oopses which provide 32-bit
addresses) and it would make objdump outputs more readable.
Fixing this problem with BFD is on my to do list (but has a low priority
assigned).
--
+ Maciej W. Rozycki, Technical University of Gdansk, Poland +
+--------------------------------------------------------------+
+ e-mail: macro@ds2.pg.gda.pl, PGP key available +
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: your mail
2001-01-04 16:22 ` Maciej W. Rozycki
@ 2001-01-04 16:40 ` Joe deBlaquiere
2001-01-04 17:13 ` Ralf Baechle
2001-01-04 17:18 ` Maciej W. Rozycki
0 siblings, 2 replies; 38+ messages in thread
From: Joe deBlaquiere @ 2001-01-04 16:40 UTC (permalink / raw)
To: Maciej W. Rozycki
Cc: Ralf Baechle, John Van Horne, 'linux-mips@oss.sgi.com',
'wesolows@foobazco.org'
If the BFD stuff is built with any support for 64 bit (even as an
optional target) it will maintain all addresses as 64-bit values, even
if the file is 32 bit.
There is a bug in that "some" newer versions of objcopy will not allow
you to translate these sign-extended 32 bit addresses into Intel Hex
format.
If you're really only doing 32-bit mips you might consider removing the
64 bit targets in the config.bfd... I think that will solve the problems.
Maciej W. Rozycki wrote:
> On Thu, 4 Jan 2001, Ralf Baechle wrote:
>
>
>>> I see that our start address of 0x80102584 has been turned into
>>> 0xffffffff80102584. I'm thinking that
>>> I need to tell ld something to stop it from doing this. Any ideas?
>>
>> That's be ok. 32-bit MIPS addresses are sign-extended into 64-bit addresses.
>> Older binutils used to zero-extend addresses which was broken. So what
>> you observe is actually the sympthom of a bug that got fixed.
>
>
> I'm not sure that's the best solution, I'm afraid. For elf32-mips
> addresses should be 32-bit and not 64-bit. It would be consistent with
> other 32-bit platforms, it would make interoperability easier (ksymoops
> cannot make use of System.map to grok kernel oopses which provide 32-bit
> addresses) and it would make objdump outputs more readable.
>
> Fixing this problem with BFD is on my to do list (but has a low priority
> assigned).
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: your mail
2001-01-04 16:40 ` Joe deBlaquiere
@ 2001-01-04 17:13 ` Ralf Baechle
2001-01-04 17:46 ` Joe deBlaquiere
2001-01-04 17:18 ` Maciej W. Rozycki
1 sibling, 1 reply; 38+ messages in thread
From: Ralf Baechle @ 2001-01-04 17:13 UTC (permalink / raw)
To: Joe deBlaquiere
Cc: Maciej W. Rozycki, John Van Horne,
'linux-mips@oss.sgi.com', 'wesolows@foobazco.org'
On Thu, Jan 04, 2001 at 10:40:41AM -0600, Joe deBlaquiere wrote:
> There is a bug in that "some" newer versions of objcopy will not allow
> you to translate these sign-extended 32 bit addresses into Intel Hex
> format.
I couldn't care less ...
> If you're really only doing 32-bit mips you might consider removing the
> 64 bit targets in the config.bfd... I think that will solve the problems.
Doesn't really solve the problem. For example on an Origin we have a 32-bit
userland but 64-bit kernel addresses which confuses ksymops and procps.
Ralf
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: your mail
2001-01-04 17:13 ` Ralf Baechle
@ 2001-01-04 17:46 ` Joe deBlaquiere
2001-01-04 18:12 ` Maciej W. Rozycki
0 siblings, 1 reply; 38+ messages in thread
From: Joe deBlaquiere @ 2001-01-04 17:46 UTC (permalink / raw)
To: Ralf Baechle
Cc: Maciej W. Rozycki, John Van Horne,
'linux-mips@oss.sgi.com', 'wesolows@foobazco.org'
Ralf Baechle wrote:
> On Thu, Jan 04, 2001 at 10:40:41AM -0600, Joe deBlaquiere wrote:
>
> If you're really only doing 32-bit mips you might consider removing the
>> 64 bit targets in the config.bfd... I think that will solve the problems.
>
>
> Doesn't really solve the problem. For example on an Origin we have a 32-bit
> userland but 64-bit kernel addresses which confuses ksymops and procps.
>
> Ralf
It was meant as a workaround...
Perhaps we could have an option to objcopy that would allow you to copy
the addresses without sign extension?
Joe
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: your mail
2001-01-04 17:46 ` Joe deBlaquiere
@ 2001-01-04 18:12 ` Maciej W. Rozycki
0 siblings, 0 replies; 38+ messages in thread
From: Maciej W. Rozycki @ 2001-01-04 18:12 UTC (permalink / raw)
To: Joe deBlaquiere
Cc: Ralf Baechle, John Van Horne, 'linux-mips@oss.sgi.com',
'wesolows@foobazco.org'
On Thu, 4 Jan 2001, Joe deBlaquiere wrote:
> It was meant as a workaround...
>
> Perhaps we could have an option to objcopy that would allow you to copy
> the addresses without sign extension?
Please do either implement a clean solution or wait until someone else
(possibly me) does. We don't want any more hacks -- MIPS/Linux already
has enough of them. This is my view of the situation at present.
--
+ Maciej W. Rozycki, Technical University of Gdansk, Poland +
+--------------------------------------------------------------+
+ e-mail: macro@ds2.pg.gda.pl, PGP key available +
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: your mail
2001-01-04 16:40 ` Joe deBlaquiere
2001-01-04 17:13 ` Ralf Baechle
@ 2001-01-04 17:18 ` Maciej W. Rozycki
1 sibling, 0 replies; 38+ messages in thread
From: Maciej W. Rozycki @ 2001-01-04 17:18 UTC (permalink / raw)
To: Joe deBlaquiere
Cc: Ralf Baechle, John Van Horne, 'linux-mips@oss.sgi.com',
'wesolows@foobazco.org'
On Thu, 4 Jan 2001, Joe deBlaquiere wrote:
> If the BFD stuff is built with any support for 64 bit (even as an
> optional target) it will maintain all addresses as 64-bit values, even
> if the file is 32 bit.
I do consider it fine BFD handles all addresses as 64-bit internally. I
just think it should truncate them to 32-bits upon printing (and always
whenever appropriate) when the selected target is 32-bit. It does so (it
has to!) for output anyway, so what's the deal?
> If you're really only doing 32-bit mips you might consider removing the
> 64 bit targets in the config.bfd... I think that will solve the problems.
Nope, I insist 32-bit targets need to work correctly regardless of
whether there are any 64-bit ones supported by a particular BFD binary or
not. Do you think elf32-i386 should switch to printing 64-bit addresses
if elf64-alpha is also supported by a given configuration of BFD? I
don't.
--
+ Maciej W. Rozycki, Technical University of Gdansk, Poland +
+--------------------------------------------------------------+
+ e-mail: macro@ds2.pg.gda.pl, PGP key available +
^ permalink raw reply [flat|nested] 38+ messages in thread
* (no subject)
@ 1997-08-09 17:16 Vincent Renardias
1997-08-09 17:41 ` your mail Ralf Baechle
0 siblings, 1 reply; 38+ messages in thread
From: Vincent Renardias @ 1997-08-09 17:16 UTC (permalink / raw)
To: linux
Hello,
I've just joined this ML, and I'm trying to contribute to the
Linux/SGI development. Since I'm not too good at kernel hacking, I've
tough about working on porting the userland part (I have some experience
with this part since I've been a Debian developper for a while and
initiated the Debian/PowerPC port).
By now I don't have access to any SGI hardware, but i've been able
to build some packages with the crossdev (i486-linux) packages from
ftp.linux.sgi.com.
So here are my questions:
1/ Which are the 'most wanted' packages not yet recompiled/ported to
Linux/SGI? I've looked at the RPMs available RPM list, and some important
packages seem unavailable yet. (sed,tar,perl come to mind).
2/ While using the crossdev gcc, several times I got complains about a
file 'sgidefs.h' missing (from
/usr/local/lib/gcc-lib/mips-linux/2.7.2/include/va-mips.h, line 41).
Commenting the '#include' file made the compile work, but I not sure it's
the right fix.
3/ Can any1 confirm/correct the following values for GNU/autoconf:
ac_cv_c_bigendian=no
ac_cv_c_char_unsigned=no
ac_cv_sizeof_long=4
ac_cv_sizeof_int=4
Cordialement,
--
- ** Linux ** +-------------------+ ** WAW ** -
- vincent@debian.org | RENARDIAS Vincent | vincent@waw.com -
- Debian/GNU Linux +-------------------+ http://www.waw.com/ -
- http://www.debian.org/ | WAW (33) 4 91 81 21 45 -
---------------------------------------------------------------------------
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: your mail
1997-08-09 17:16 Vincent Renardias
@ 1997-08-09 17:41 ` Ralf Baechle
1997-08-09 17:41 ` Ralf Baechle
1997-08-09 19:40 ` Vincent Renardias
0 siblings, 2 replies; 38+ messages in thread
From: Ralf Baechle @ 1997-08-09 17:41 UTC (permalink / raw)
To: Vincent Renardias; +Cc: linux
> I've just joined this ML, and I'm trying to contribute to the
> Linux/SGI development. Since I'm not too good at kernel hacking, I've
> tough about working on porting the userland part (I have some experience
> with this part since I've been a Debian developper for a while and
> initiated the Debian/PowerPC port).
> By now I don't have access to any SGI hardware, but i've been able
> to build some packages with the crossdev (i486-linux) packages from
> ftp.linux.sgi.com.
>
> So here are my questions:
>
> 1/ Which are the 'most wanted' packages not yet recompiled/ported to
> Linux/SGI? I've looked at the RPMs available RPM list, and some important
> packages seem unavailable yet. (sed,tar,perl come to mind).
sed, tar: confilicting declaration in source and libc. Both work other-
wise. Perl: builds shrink wrapped & works, just the binary packaging
with RPM fails. I think because groff/man are missing. I've got another
two dozen packages on disk which I'll upload when I next pass by in
Mountain View ...
> 2/ While using the crossdev gcc, several times I got complains about a
> file 'sgidefs.h' missing (from
> /usr/local/lib/gcc-lib/mips-linux/2.7.2/include/va-mips.h, line 41).
> Commenting the '#include' file made the compile work, but I not sure it's
> the right fix.
Not the right thing, but won't hurt. I shows that your libc is
not installed correctly.
> 3/ Can any1 confirm/correct the following values for GNU/autoconf:
> ac_cv_c_bigendian=no
MIPS CPUs can be configured for both byte orders. SGI, Mips Inc.,
Sony machines are wired big endian, most other machines are little
endian or configurable by replacing the firmware. As a consequence
we have to build all packages twice, once for each byte sex.
mips-linux-* tools are big endian by default, mipsel-linux-* tools
little endian.
> ac_cv_c_char_unsigned=no
True by default, unless you give -funsigned-char.
> ac_cv_sizeof_long=4
> ac_cv_sizeof_int=4
True by default in the mips{el}-linux configurations; the size of
these types can be changed by -mlong64 and -mint64. These options
are incompatible with libc, so I mention them only for completeness.
Ralf
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: your mail
1997-08-09 17:41 ` your mail Ralf Baechle
@ 1997-08-09 17:41 ` Ralf Baechle
1997-08-09 19:40 ` Vincent Renardias
1 sibling, 0 replies; 38+ messages in thread
From: Ralf Baechle @ 1997-08-09 17:41 UTC (permalink / raw)
To: Vincent Renardias; +Cc: linux
> I've just joined this ML, and I'm trying to contribute to the
> Linux/SGI development. Since I'm not too good at kernel hacking, I've
> tough about working on porting the userland part (I have some experience
> with this part since I've been a Debian developper for a while and
> initiated the Debian/PowerPC port).
> By now I don't have access to any SGI hardware, but i've been able
> to build some packages with the crossdev (i486-linux) packages from
> ftp.linux.sgi.com.
>
> So here are my questions:
>
> 1/ Which are the 'most wanted' packages not yet recompiled/ported to
> Linux/SGI? I've looked at the RPMs available RPM list, and some important
> packages seem unavailable yet. (sed,tar,perl come to mind).
sed, tar: confilicting declaration in source and libc. Both work other-
wise. Perl: builds shrink wrapped & works, just the binary packaging
with RPM fails. I think because groff/man are missing. I've got another
two dozen packages on disk which I'll upload when I next pass by in
Mountain View ...
> 2/ While using the crossdev gcc, several times I got complains about a
> file 'sgidefs.h' missing (from
> /usr/local/lib/gcc-lib/mips-linux/2.7.2/include/va-mips.h, line 41).
> Commenting the '#include' file made the compile work, but I not sure it's
> the right fix.
Not the right thing, but won't hurt. I shows that your libc is
not installed correctly.
> 3/ Can any1 confirm/correct the following values for GNU/autoconf:
> ac_cv_c_bigendian=no
MIPS CPUs can be configured for both byte orders. SGI, Mips Inc.,
Sony machines are wired big endian, most other machines are little
endian or configurable by replacing the firmware. As a consequence
we have to build all packages twice, once for each byte sex.
mips-linux-* tools are big endian by default, mipsel-linux-* tools
little endian.
> ac_cv_c_char_unsigned=no
True by default, unless you give -funsigned-char.
> ac_cv_sizeof_long=4
> ac_cv_sizeof_int=4
True by default in the mips{el}-linux configurations; the size of
these types can be changed by -mlong64 and -mint64. These options
are incompatible with libc, so I mention them only for completeness.
Ralf
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: your mail
1997-08-09 17:41 ` your mail Ralf Baechle
1997-08-09 17:41 ` Ralf Baechle
@ 1997-08-09 19:40 ` Vincent Renardias
1997-08-09 19:42 ` Ralf Baechle
1 sibling, 1 reply; 38+ messages in thread
From: Vincent Renardias @ 1997-08-09 19:40 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux
On Sat, 9 Aug 1997, Ralf Baechle wrote:
> > 2/ While using the crossdev gcc, several times I got complains about a
> > file 'sgidefs.h' missing (from
> > /usr/local/lib/gcc-lib/mips-linux/2.7.2/include/va-mips.h, line 41).
> > Commenting the '#include' file made the compile work, but I not sure it's
> > the right fix.
>
> Not the right thing, but won't hurt. I shows that your libc is
> not installed correctly.
I just installed the binutils/gcc crossdev packages from
ftp.linux.sgi.com. Should i also install the glibc-2.0.4-1.tar.gz package
from /pub/mips-linux? In case it matters my native libc is glibc-2.0.4
(i386).
[Thanx for the explanation on endianess ;]
Cordialement,
--
- ** Linux ** +-------------------+ ** WAW ** -
- vincent@debian.org | RENARDIAS Vincent | vincent@waw.com -
- Debian/GNU Linux +-------------------+ http://www.waw.com/ -
- http://www.debian.org/ | WAW (33) 4 91 81 21 45 -
---------------------------------------------------------------------------
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: your mail
1997-08-09 19:40 ` Vincent Renardias
@ 1997-08-09 19:42 ` Ralf Baechle
1997-08-09 19:42 ` Ralf Baechle
1997-08-09 21:05 ` Vincent Renardias
0 siblings, 2 replies; 38+ messages in thread
From: Ralf Baechle @ 1997-08-09 19:42 UTC (permalink / raw)
To: Vincent Renardias; +Cc: ralf, linux
> > Not the right thing, but won't hurt. I shows that your libc is
> > not installed correctly.
>
> I just installed the binutils/gcc crossdev packages from
> ftp.linux.sgi.com. Should i also install the glibc-2.0.4-1.tar.gz package
> from /pub/mips-linux? In case it matters my native libc is glibc-2.0.4
> (i386).
Well, it doesn't matter except that I built the executables with Linux
libc and you therefore need that one. DANGER: When you install libs
for a crosscompiler you will have to move the libs a bit around.
Just doing tar zxf ... -C / will fry your native system. MIPS stuff
just has too much octane to be suitable as fuel for your Intel machine ;-)
Btw, as I'm writing this I've built about 88mb of binary .rpm packages
running native. The sole problems I currently have is that the kernel
seems to have some memory corruption problem. That is nasty because
it usually hits the bitmaps ... It might as well explain Miguel's
recently reported NFS problem.
Ralf
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: your mail
1997-08-09 19:42 ` Ralf Baechle
@ 1997-08-09 19:42 ` Ralf Baechle
1997-08-09 21:05 ` Vincent Renardias
1 sibling, 0 replies; 38+ messages in thread
From: Ralf Baechle @ 1997-08-09 19:42 UTC (permalink / raw)
To: Vincent Renardias; +Cc: ralf, linux
> > Not the right thing, but won't hurt. I shows that your libc is
> > not installed correctly.
>
> I just installed the binutils/gcc crossdev packages from
> ftp.linux.sgi.com. Should i also install the glibc-2.0.4-1.tar.gz package
> from /pub/mips-linux? In case it matters my native libc is glibc-2.0.4
> (i386).
Well, it doesn't matter except that I built the executables with Linux
libc and you therefore need that one. DANGER: When you install libs
for a crosscompiler you will have to move the libs a bit around.
Just doing tar zxf ... -C / will fry your native system. MIPS stuff
just has too much octane to be suitable as fuel for your Intel machine ;-)
Btw, as I'm writing this I've built about 88mb of binary .rpm packages
running native. The sole problems I currently have is that the kernel
seems to have some memory corruption problem. That is nasty because
it usually hits the bitmaps ... It might as well explain Miguel's
recently reported NFS problem.
Ralf
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: your mail
1997-08-09 19:42 ` Ralf Baechle
1997-08-09 19:42 ` Ralf Baechle
@ 1997-08-09 21:05 ` Vincent Renardias
1997-08-09 21:11 ` Ralf Baechle
1997-08-09 22:53 ` Mike Shaver
1 sibling, 2 replies; 38+ messages in thread
From: Vincent Renardias @ 1997-08-09 21:05 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux
On Sat, 9 Aug 1997, Ralf Baechle wrote:
> > I just installed the binutils/gcc crossdev packages from
> > ftp.linux.sgi.com. Should i also install the glibc-2.0.4-1.tar.gz package
> > from /pub/mips-linux? In case it matters my native libc is glibc-2.0.4
> > (i386).
>
> Well, it doesn't matter except that I built the executables with Linux
> libc and you therefore need that one. DANGER: When you install libs
> for a crosscompiler you will have to move the libs a bit around.
> Just doing tar zxf ... -C / will fry your native system. MIPS stuff
> just has too much octane to be suitable as fuel for your Intel machine ;-)
Debian provides nice tools to handdle this kind of installation:
- alien: allows to convert binary packages between any 2 of the
{.deb,.tgz,.rpm} formats.
- dpkg-cross: tool handdling cross-compilation packages. That is any file
that should go into /*/lib is redirected into /usr/local/$ARCH-linux/lib.
(same for the include files). It also makes it possible to build a given
package for several architectures at the same time.
Those tools should probably work on any Linux flavour (distrib./arch.)
Anyway, I've installed glibc-2.0.4 to get around the missing sgidefs.h
problem, and I run into another problem:
now mips-linux-gcc complains about:
% mips-linux-gcc -o pwgen pwgen.o -lm
/usr/local/mips-linux/lib/libc.a: could not read symbols: Archive has no
index; run ranlib to add one
running mips-linux-ranlib on the given file does not change anything.
(ie: still getting the same message)
Did I do anything wrong, or is this a problem in the Linux/SGI glibc?
Cordialement,
--
- ** Linux ** +-------------------+ ** WAW ** -
- vincent@debian.org | RENARDIAS Vincent | vincent@waw.com -
- Debian/GNU Linux +-------------------+ http://www.waw.com/ -
- http://www.debian.org/ | WAW (33) 4 91 81 21 45 -
---------------------------------------------------------------------------
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: your mail
1997-08-09 21:05 ` Vincent Renardias
@ 1997-08-09 21:11 ` Ralf Baechle
1997-08-09 21:11 ` Ralf Baechle
1997-08-10 2:57 ` Vincent Renardias
1997-08-09 22:53 ` Mike Shaver
1 sibling, 2 replies; 38+ messages in thread
From: Ralf Baechle @ 1997-08-09 21:11 UTC (permalink / raw)
To: Vincent Renardias; +Cc: ralf, linux
> % mips-linux-gcc -o pwgen pwgen.o -lm
> /usr/local/mips-linux/lib/libc.a: could not read symbols: Archive has no
> index; run ranlib to add one
>
> running mips-linux-ranlib on the given file does not change anything.
> (ie: still getting the same message)
>
> Did I do anything wrong, or is this a problem in the Linux/SGI glibc?
No. Looks as if your lib still isn't correctly installed. If ranlib
doesn't help, then your libc.a is probably corrupted into a zero lenght
file.
Ralf
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: your mail
1997-08-09 21:11 ` Ralf Baechle
@ 1997-08-09 21:11 ` Ralf Baechle
1997-08-10 2:57 ` Vincent Renardias
1 sibling, 0 replies; 38+ messages in thread
From: Ralf Baechle @ 1997-08-09 21:11 UTC (permalink / raw)
To: Vincent Renardias; +Cc: ralf, linux
> % mips-linux-gcc -o pwgen pwgen.o -lm
> /usr/local/mips-linux/lib/libc.a: could not read symbols: Archive has no
> index; run ranlib to add one
>
> running mips-linux-ranlib on the given file does not change anything.
> (ie: still getting the same message)
>
> Did I do anything wrong, or is this a problem in the Linux/SGI glibc?
No. Looks as if your lib still isn't correctly installed. If ranlib
doesn't help, then your libc.a is probably corrupted into a zero lenght
file.
Ralf
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: your mail
1997-08-09 21:11 ` Ralf Baechle
1997-08-09 21:11 ` Ralf Baechle
@ 1997-08-10 2:57 ` Vincent Renardias
1 sibling, 0 replies; 38+ messages in thread
From: Vincent Renardias @ 1997-08-10 2:57 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux
On Sat, 9 Aug 1997, Ralf Baechle wrote:
> > % mips-linux-gcc -o pwgen pwgen.o -lm
> > /usr/local/mips-linux/lib/libc.a: could not read symbols: Archive has no
> > index; run ranlib to add one
> >
> > running mips-linux-ranlib on the given file does not change anything.
> > (ie: still getting the same message)
> >
> > Did I do anything wrong, or is this a problem in the Linux/SGI glibc?
>
> No. Looks as if your lib still isn't correctly installed. If ranlib
> doesn't help, then your libc.a is probably corrupted into a zero lenght
> file.
You're right. (Not an empty file through, but somehow it got truncated to
~50 K). Reinstalling fixed it.
Here's the list of what I compiled so far:
file_3.20.1-6_mips.deb gzip_1.2.4-15_mips.deb
debmake_3.3.11_mips.deb grep_2.0-12_mips.deb
dpkg-dev_1.4.0.8_all.deb makedev_1.6-16_mips.deb
dpkg_1.4.0.8_mips.deb sysklogd_1.3-17_mips.deb
dpkg_1.4.0.8_mips.nondebbin.tar.gz update_1.3-1_mips.deb
cpio_2.4.2-11_mips.deb tar_1.12-1_mips.deb
patch_2.2-1_mips.deb sed_2.05-15_mips.deb
flex_2.5.4a-1_mips.deb findutils_4.1-23_mips.deb
bison_1.25-9_mips.deb shellutils_1.16-4_mips.deb
diff_2.7-13_mips.deb textutils_1.22-2_mips.deb
rpm_2.4.2-2_mips.deb pwgen_1-8_mips.deb
adduser_3.6_all.deb
These packages are available from odin.waw.com/pub/linux (the pgp signed
checksums are in the changes/ subdirectory). I'd be glad if someone could
test a few of them and tell me if everything is okay.
Quick install instructions:
untar the file dpkg_1.4.0.8_mips.nondebbin.tar.gz at the root of your FS,
then install other packages with 'dpkg -i foo.deb'.
Cordialement,
--
- ** Linux ** +-------------------+ ** WAW ** -
- vincent@debian.org | RENARDIAS Vincent | vincent@waw.com -
- Debian/GNU Linux +-------------------+ http://www.waw.com/ -
- http://www.debian.org/ | WAW (33) 4 91 81 21 45 -
---------------------------------------------------------------------------
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: your mail
1997-08-09 21:05 ` Vincent Renardias
1997-08-09 21:11 ` Ralf Baechle
@ 1997-08-09 22:53 ` Mike Shaver
1997-08-09 22:53 ` Mike Shaver
1 sibling, 1 reply; 38+ messages in thread
From: Mike Shaver @ 1997-08-09 22:53 UTC (permalink / raw)
To: Vincent Renardias; +Cc: ralf, linux
Thus spake Vincent Renardias:
> % mips-linux-gcc -o pwgen pwgen.o -lm
> /usr/local/mips-linux/lib/libc.a: could not read symbols: Archive has no
> index; run ranlib to add one
>
> running mips-linux-ranlib on the given file does not change anything.
> (ie: still getting the same message)
Did you use mips-linux-ar to create the archive?
Many packages, I've discovered, don't listen to $AR in the
environment, and I used to get that error all the time.
Mike
--
#> Mike Shaver (shaver@ingenia.com) Ingenia Communications Corporation
#> Chief System Architect and Herder of Bits
#>
#> "Yoda say, `Just slap a little public key crypto into it' does not
#> a secure system make." -- Marcus J. Ranum (mjr@clark.net)
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: your mail
1997-08-09 22:53 ` Mike Shaver
@ 1997-08-09 22:53 ` Mike Shaver
0 siblings, 0 replies; 38+ messages in thread
From: Mike Shaver @ 1997-08-09 22:53 UTC (permalink / raw)
To: Vincent Renardias; +Cc: ralf, linux
Thus spake Vincent Renardias:
> % mips-linux-gcc -o pwgen pwgen.o -lm
> /usr/local/mips-linux/lib/libc.a: could not read symbols: Archive has no
> index; run ranlib to add one
>
> running mips-linux-ranlib on the given file does not change anything.
> (ie: still getting the same message)
Did you use mips-linux-ar to create the archive?
Many packages, I've discovered, don't listen to $AR in the
environment, and I used to get that error all the time.
Mike
--
#> Mike Shaver (shaver@ingenia.com) Ingenia Communications Corporation
#> Chief System Architect and Herder of Bits
#>
#> "Yoda say, `Just slap a little public key crypto into it' does not
#> a secure system make." -- Marcus J. Ranum (mjr@clark.net)
^ permalink raw reply [flat|nested] 38+ messages in thread
end of thread, other threads:[~2020-05-07 11:43 UTC | newest]
Thread overview: 38+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-01-22 0:00 (no subject) Thiemo Seufer
2008-01-28 17:51 ` your mail Ralf Baechle
2008-01-28 20:05 ` Split the micro-assembler from tlbex.c (was: Re: your mail) Thiemo Seufer
2008-01-28 22:53 ` Ralf Baechle
-- strict thread matches above, loose matches on Subject: below --
2020-05-06 5:52 Jiaxun Yang
2020-05-07 11:00 ` your mail Thomas Bogendoerfer
2018-08-27 14:50 Christoph Hellwig
2018-08-31 20:23 ` your mail Paul Burton
2018-03-09 15:12 [PATCH 00/14] Enable SD/MMC on JZ4780 SoCs Ezequiel Garcia
2018-03-09 15:12 ` [PATCH 08/14] mmc: jz4740: Add support for the JZ4780 Ezequiel Garcia
2018-03-09 17:51 ` [PATCH 08/14] mmc: jz4740: Add support for the JZ4780, Paul Cercueil
2018-03-09 22:31 ` your mail James Hogan
2018-03-09 22:31 ` James Hogan
2005-04-28 19:15 Bryan Althouse
2005-04-29 11:02 ` your mail Ralf Baechle
2003-04-18 0:08 Dennis Castleman
2003-04-17 17:53 Dennis Castleman
2003-04-17 18:17 ` your mail Jun Sun
2003-04-17 20:15 ` Greg Lindahl
2003-04-18 0:03 ` Ralf Baechle
2003-03-29 6:54 Avinash S.
2003-03-29 7:25 ` your mail Thiemo Seufer
2002-10-26 19:48 Zajerko-McKee, Nick
2002-10-26 20:08 ` your mail Daniel Jacobowitz
2002-10-26 20:32 ` Greg Lindahl
2001-10-03 14:28 Marian Kafadarov
2001-10-03 15:52 ` your mail Martin Schulze
[not found] <5.0.0.25.0.20010404172906.00a4bce8@vmspop.isc.rit.edu>
2001-04-04 21:37 ` Matthew Fredrickson
2001-04-05 5:08 ` Ralf Baechle
2001-02-15 0:27 Deepa Suresh
2001-02-15 11:03 ` your mail Geert Uytterhoeven
2001-01-04 1:36 John Van Horne
2001-01-04 15:36 ` your mail Ralf Baechle
2001-01-04 16:22 ` Maciej W. Rozycki
2001-01-04 16:40 ` Joe deBlaquiere
2001-01-04 17:13 ` Ralf Baechle
2001-01-04 17:46 ` Joe deBlaquiere
2001-01-04 18:12 ` Maciej W. Rozycki
2001-01-04 17:18 ` Maciej W. Rozycki
1997-08-09 17:16 Vincent Renardias
1997-08-09 17:41 ` your mail Ralf Baechle
1997-08-09 17:41 ` Ralf Baechle
1997-08-09 19:40 ` Vincent Renardias
1997-08-09 19:42 ` Ralf Baechle
1997-08-09 19:42 ` Ralf Baechle
1997-08-09 21:05 ` Vincent Renardias
1997-08-09 21:11 ` Ralf Baechle
1997-08-09 21:11 ` Ralf Baechle
1997-08-10 2:57 ` Vincent Renardias
1997-08-09 22:53 ` Mike Shaver
1997-08-09 22:53 ` Mike Shaver
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).