lkml.org 
[lkml]   [2010]   [Jul]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3/7] MIPS: Add option to export uasm API.
    Date
    A 'select EXPORT_UASM' in Kconfig will cause the uasm to be exported
    for use in modules. When it is exported, all the uasm data and code
    cease to be __init and __initdata.

    Also daddiu_bug cannot be __cpuinitdata if uasm is exported. The
    cleanest thing is to just make it normal data.

    Signed-off-by: David Daney <ddaney@caviumnetworks.com>
    ---
    arch/mips/Kconfig | 3 +
    arch/mips/include/asm/uasm.h | 37 ++++++++----
    arch/mips/kernel/cpu-bugs64.c | 2 +-
    arch/mips/mm/uasm.c | 131 +++++++++++++++++++++++++---------------
    4 files changed, 110 insertions(+), 63 deletions(-)

    diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
    index cdaae94..4588f42 100644
    --- a/arch/mips/Kconfig
    +++ b/arch/mips/Kconfig
    @@ -892,6 +892,9 @@ config CPU_LITTLE_ENDIAN

    endchoice

    +config EXPORT_UASM
    + bool
    +
    config SYS_SUPPORTS_APM_EMULATION
    bool

    diff --git a/arch/mips/include/asm/uasm.h b/arch/mips/include/asm/uasm.h
    index db9d449..892062d 100644
    --- a/arch/mips/include/asm/uasm.h
    +++ b/arch/mips/include/asm/uasm.h
    @@ -10,44 +10,55 @@

    #include <linux/types.h>

    +#ifdef CONFIG_EXPORT_UASM
    +#include <linux/module.h>
    +#define __uasminit
    +#define __uasminitdata
    +#define UASM_EXPORT_SYMBOL(sym) EXPORT_SYMBOL(sym)
    +#else
    +#define __uasminit __cpuinit
    +#define __uasminitdata __cpuinitdata
    +#define UASM_EXPORT_SYMBOL(sym)
    +#endif
    +
    #define Ip_u1u2u3(op) \
    -void __cpuinit \
    +void __uasminit \
    uasm_i##op(u32 **buf, unsigned int a, unsigned int b, unsigned int c)

    #define Ip_u2u1u3(op) \
    -void __cpuinit \
    +void __uasminit \
    uasm_i##op(u32 **buf, unsigned int a, unsigned int b, unsigned int c)

    #define Ip_u3u1u2(op) \
    -void __cpuinit \
    +void __uasminit \
    uasm_i##op(u32 **buf, unsigned int a, unsigned int b, unsigned int c)

    #define Ip_u1u2s3(op) \
    -void __cpuinit \
    +void __uasminit \
    uasm_i##op(u32 **buf, unsigned int a, unsigned int b, signed int c)

    #define Ip_u2s3u1(op) \
    -void __cpuinit \
    +void __uasminit \
    uasm_i##op(u32 **buf, unsigned int a, signed int b, unsigned int c)

    #define Ip_u2u1s3(op) \
    -void __cpuinit \
    +void __uasminit \
    uasm_i##op(u32 **buf, unsigned int a, unsigned int b, signed int c)

    #define Ip_u2u1msbu3(op) \
    -void __cpuinit \
    +void __uasminit \
    uasm_i##op(u32 **buf, unsigned int a, unsigned int b, unsigned int c, \
    unsigned int d)

    #define Ip_u1u2(op) \
    -void __cpuinit uasm_i##op(u32 **buf, unsigned int a, unsigned int b)
    +void __uasminit uasm_i##op(u32 **buf, unsigned int a, unsigned int b)

    #define Ip_u1s2(op) \
    -void __cpuinit uasm_i##op(u32 **buf, unsigned int a, signed int b)
    +void __uasminit uasm_i##op(u32 **buf, unsigned int a, signed int b)

    -#define Ip_u1(op) void __cpuinit uasm_i##op(u32 **buf, unsigned int a)
    +#define Ip_u1(op) void __uasminit uasm_i##op(u32 **buf, unsigned int a)

    -#define Ip_0(op) void __cpuinit uasm_i##op(u32 **buf)
    +#define Ip_0(op) void __uasminit uasm_i##op(u32 **buf)

    Ip_u2u1s3(_addiu);
    Ip_u3u1u2(_addu);
    @@ -112,7 +123,7 @@ struct uasm_label {
    int lab;
    };

    -void __cpuinit uasm_build_label(struct uasm_label **lab, u32 *addr, int lid);
    +void __uasminit uasm_build_label(struct uasm_label **lab, u32 *addr, int lid);
    #ifdef CONFIG_64BIT
    int uasm_in_compat_space_p(long addr);
    #endif
    @@ -122,7 +133,7 @@ void UASM_i_LA_mostly(u32 **buf, unsigned int rs, long addr);
    void UASM_i_LA(u32 **buf, unsigned int rs, long addr);

    #define UASM_L_LA(lb) \
    -static inline void __cpuinit uasm_l##lb(struct uasm_label **lab, u32 *addr) \
    +static inline void __uasminit uasm_l##lb(struct uasm_label **lab, u32 *addr) \
    { \
    uasm_build_label(lab, addr, label##lb); \
    }
    diff --git a/arch/mips/kernel/cpu-bugs64.c b/arch/mips/kernel/cpu-bugs64.c
    index 408d0a0..b8bb8ba 100644
    --- a/arch/mips/kernel/cpu-bugs64.c
    +++ b/arch/mips/kernel/cpu-bugs64.c
    @@ -239,7 +239,7 @@ static inline void check_daddi(void)
    panic(bug64hit, !DADDI_WAR ? daddiwar : nowar);
    }

    -int daddiu_bug __cpuinitdata = -1;
    +int daddiu_bug = -1;

    static inline void check_daddiu(void)
    {
    diff --git a/arch/mips/mm/uasm.c b/arch/mips/mm/uasm.c
    index 636b817..d2647a4 100644
    --- a/arch/mips/mm/uasm.c
    +++ b/arch/mips/mm/uasm.c
    @@ -86,7 +86,7 @@ struct insn {
    | (e) << RE_SH \
    | (f) << FUNC_SH)

    -static struct insn insn_table[] __cpuinitdata = {
    +static struct insn insn_table[] __uasminitdata = {
    { 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 },
    @@ -150,7 +150,7 @@ static struct insn insn_table[] __cpuinitdata = {

    #undef M

    -static inline __cpuinit u32 build_rs(u32 arg)
    +static inline __uasminit u32 build_rs(u32 arg)
    {
    if (arg & ~RS_MASK)
    printk(KERN_WARNING "Micro-assembler field overflow\n");
    @@ -158,7 +158,7 @@ static inline __cpuinit u32 build_rs(u32 arg)
    return (arg & RS_MASK) << RS_SH;
    }

    -static inline __cpuinit u32 build_rt(u32 arg)
    +static inline __uasminit u32 build_rt(u32 arg)
    {
    if (arg & ~RT_MASK)
    printk(KERN_WARNING "Micro-assembler field overflow\n");
    @@ -166,7 +166,7 @@ static inline __cpuinit u32 build_rt(u32 arg)
    return (arg & RT_MASK) << RT_SH;
    }

    -static inline __cpuinit u32 build_rd(u32 arg)
    +static inline __uasminit u32 build_rd(u32 arg)
    {
    if (arg & ~RD_MASK)
    printk(KERN_WARNING "Micro-assembler field overflow\n");
    @@ -174,7 +174,7 @@ static inline __cpuinit u32 build_rd(u32 arg)
    return (arg & RD_MASK) << RD_SH;
    }

    -static inline __cpuinit u32 build_re(u32 arg)
    +static inline __uasminit u32 build_re(u32 arg)
    {
    if (arg & ~RE_MASK)
    printk(KERN_WARNING "Micro-assembler field overflow\n");
    @@ -182,7 +182,7 @@ static inline __cpuinit u32 build_re(u32 arg)
    return (arg & RE_MASK) << RE_SH;
    }

    -static inline __cpuinit u32 build_simm(s32 arg)
    +static inline __uasminit u32 build_simm(s32 arg)
    {
    if (arg > 0x7fff || arg < -0x8000)
    printk(KERN_WARNING "Micro-assembler field overflow\n");
    @@ -190,7 +190,7 @@ static inline __cpuinit u32 build_simm(s32 arg)
    return arg & 0xffff;
    }

    -static inline __cpuinit u32 build_uimm(u32 arg)
    +static inline __uasminit u32 build_uimm(u32 arg)
    {
    if (arg & ~IMM_MASK)
    printk(KERN_WARNING "Micro-assembler field overflow\n");
    @@ -198,7 +198,7 @@ static inline __cpuinit u32 build_uimm(u32 arg)
    return arg & IMM_MASK;
    }

    -static inline __cpuinit u32 build_bimm(s32 arg)
    +static inline __uasminit u32 build_bimm(s32 arg)
    {
    if (arg > 0x1ffff || arg < -0x20000)
    printk(KERN_WARNING "Micro-assembler field overflow\n");
    @@ -209,7 +209,7 @@ static inline __cpuinit u32 build_bimm(s32 arg)
    return ((arg < 0) ? (1 << 15) : 0) | ((arg >> 2) & 0x7fff);
    }

    -static inline __cpuinit u32 build_jimm(u32 arg)
    +static inline __uasminit u32 build_jimm(u32 arg)
    {
    if (arg & ~((JIMM_MASK) << 2))
    printk(KERN_WARNING "Micro-assembler field overflow\n");
    @@ -217,7 +217,7 @@ static inline __cpuinit u32 build_jimm(u32 arg)
    return (arg >> 2) & JIMM_MASK;
    }

    -static inline __cpuinit u32 build_scimm(u32 arg)
    +static inline __uasminit u32 build_scimm(u32 arg)
    {
    if (arg & ~SCIMM_MASK)
    printk(KERN_WARNING "Micro-assembler field overflow\n");
    @@ -225,7 +225,7 @@ static inline __cpuinit u32 build_scimm(u32 arg)
    return (arg & SCIMM_MASK) << SCIMM_SH;
    }

    -static inline __cpuinit u32 build_func(u32 arg)
    +static inline __uasminit u32 build_func(u32 arg)
    {
    if (arg & ~FUNC_MASK)
    printk(KERN_WARNING "Micro-assembler field overflow\n");
    @@ -233,7 +233,7 @@ static inline __cpuinit u32 build_func(u32 arg)
    return arg & FUNC_MASK;
    }

    -static inline __cpuinit u32 build_set(u32 arg)
    +static inline __uasminit u32 build_set(u32 arg)
    {
    if (arg & ~SET_MASK)
    printk(KERN_WARNING "Micro-assembler field overflow\n");
    @@ -245,7 +245,7 @@ static inline __cpuinit u32 build_set(u32 arg)
    * The order of opcode arguments is implicitly left to right,
    * starting with RS and ending with FUNC or IMM.
    */
    -static void __cpuinit build_insn(u32 **buf, enum opcode opc, ...)
    +static void __uasminit build_insn(u32 **buf, enum opcode opc, ...)
    {
    struct insn *ip = NULL;
    unsigned int i;
    @@ -295,67 +295,78 @@ static void __cpuinit build_insn(u32 **buf, enum opcode opc, ...)
    Ip_u1u2u3(op) \
    { \
    build_insn(buf, insn##op, a, b, c); \
    -}
    +} \
    +UASM_EXPORT_SYMBOL(uasm_i##op);

    #define I_u2u1u3(op) \
    Ip_u2u1u3(op) \
    { \
    build_insn(buf, insn##op, b, a, c); \
    -}
    +} \
    +UASM_EXPORT_SYMBOL(uasm_i##op);

    #define I_u3u1u2(op) \
    Ip_u3u1u2(op) \
    { \
    build_insn(buf, insn##op, b, c, a); \
    -}
    +} \
    +UASM_EXPORT_SYMBOL(uasm_i##op);

    #define I_u1u2s3(op) \
    Ip_u1u2s3(op) \
    { \
    build_insn(buf, insn##op, a, b, c); \
    -}
    +} \
    +UASM_EXPORT_SYMBOL(uasm_i##op);

    #define I_u2s3u1(op) \
    Ip_u2s3u1(op) \
    { \
    build_insn(buf, insn##op, c, a, b); \
    -}
    +} \
    +UASM_EXPORT_SYMBOL(uasm_i##op);

    #define I_u2u1s3(op) \
    Ip_u2u1s3(op) \
    { \
    build_insn(buf, insn##op, b, a, c); \
    -}
    +} \
    +UASM_EXPORT_SYMBOL(uasm_i##op);

    #define I_u2u1msbu3(op) \
    Ip_u2u1msbu3(op) \
    { \
    build_insn(buf, insn##op, b, a, c+d-1, c); \
    -}
    +} \
    +UASM_EXPORT_SYMBOL(uasm_i##op);

    #define I_u1u2(op) \
    Ip_u1u2(op) \
    { \
    build_insn(buf, insn##op, a, b); \
    -}
    +} \
    +UASM_EXPORT_SYMBOL(uasm_i##op);

    #define I_u1s2(op) \
    Ip_u1s2(op) \
    { \
    build_insn(buf, insn##op, a, b); \
    -}
    +} \
    +UASM_EXPORT_SYMBOL(uasm_i##op);

    #define I_u1(op) \
    Ip_u1(op) \
    { \
    build_insn(buf, insn##op, a); \
    -}
    +} \
    +UASM_EXPORT_SYMBOL(uasm_i##op);

    #define I_0(op) \
    Ip_0(op) \
    { \
    build_insn(buf, insn##op); \
    -}
    +} \
    +UASM_EXPORT_SYMBOL(uasm_i##op);

    I_u2u1s3(_addiu)
    I_u3u1u2(_addu)
    @@ -417,14 +428,15 @@ I_u1u2s3(_bbit0);
    I_u1u2s3(_bbit1);

    /* Handle labels. */
    -void __cpuinit uasm_build_label(struct uasm_label **lab, u32 *addr, int lid)
    +void __uasminit uasm_build_label(struct uasm_label **lab, u32 *addr, int lid)
    {
    (*lab)->addr = addr;
    (*lab)->lab = lid;
    (*lab)++;
    }
    +UASM_EXPORT_SYMBOL(uasm_build_label);

    -int __cpuinit uasm_in_compat_space_p(long addr)
    +int __uasminit uasm_in_compat_space_p(long addr)
    {
    /* Is this address in 32bit compat space? */
    #ifdef CONFIG_64BIT
    @@ -433,8 +445,9 @@ int __cpuinit uasm_in_compat_space_p(long addr)
    return 1;
    #endif
    }
    +UASM_EXPORT_SYMBOL(uasm_in_compat_space_p);

    -static int __cpuinit uasm_rel_highest(long val)
    +static int __uasminit uasm_rel_highest(long val)
    {
    #ifdef CONFIG_64BIT
    return ((((val + 0x800080008000L) >> 48) & 0xffff) ^ 0x8000) - 0x8000;
    @@ -443,7 +456,7 @@ static int __cpuinit uasm_rel_highest(long val)
    #endif
    }

    -static int __cpuinit uasm_rel_higher(long val)
    +static int __uasminit uasm_rel_higher(long val)
    {
    #ifdef CONFIG_64BIT
    return ((((val + 0x80008000L) >> 32) & 0xffff) ^ 0x8000) - 0x8000;
    @@ -452,17 +465,19 @@ static int __cpuinit uasm_rel_higher(long val)
    #endif
    }

    -int __cpuinit uasm_rel_hi(long val)
    +int __uasminit uasm_rel_hi(long val)
    {
    return ((((val + 0x8000L) >> 16) & 0xffff) ^ 0x8000) - 0x8000;
    }
    +UASM_EXPORT_SYMBOL(uasm_rel_hi);

    -int __cpuinit uasm_rel_lo(long val)
    +int __uasminit uasm_rel_lo(long val)
    {
    return ((val & 0xffff) ^ 0x8000) - 0x8000;
    }
    +UASM_EXPORT_SYMBOL(uasm_rel_lo);

    -void __cpuinit UASM_i_LA_mostly(u32 **buf, unsigned int rs, long addr)
    +void __uasminit 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));
    @@ -477,8 +492,9 @@ void __cpuinit UASM_i_LA_mostly(u32 **buf, unsigned int rs, long addr)
    } else
    uasm_i_lui(buf, rs, uasm_rel_hi(addr));
    }
    +UASM_EXPORT_SYMBOL(UASM_i_LA_mostly);

    -void __cpuinit UASM_i_LA(u32 **buf, unsigned int rs, long addr)
    +void __uasminit UASM_i_LA(u32 **buf, unsigned int rs, long addr)
    {
    UASM_i_LA_mostly(buf, rs, addr);
    if (uasm_rel_lo(addr)) {
    @@ -488,9 +504,10 @@ void __cpuinit UASM_i_LA(u32 **buf, unsigned int rs, long addr)
    uasm_i_addiu(buf, rs, rs, uasm_rel_lo(addr));
    }
    }
    +UASM_EXPORT_SYMBOL(UASM_i_LA);

    /* Handle relocations. */
    -void __cpuinit
    +void __uasminit
    uasm_r_mips_pc16(struct uasm_reloc **rel, u32 *addr, int lid)
    {
    (*rel)->addr = addr;
    @@ -498,8 +515,9 @@ uasm_r_mips_pc16(struct uasm_reloc **rel, u32 *addr, int lid)
    (*rel)->lab = lid;
    (*rel)++;
    }
    +UASM_EXPORT_SYMBOL(uasm_r_mips_pc16);

    -static inline void __cpuinit
    +static inline void __uasminit
    __resolve_relocs(struct uasm_reloc *rel, struct uasm_label *lab)
    {
    long laddr = (long)lab->addr;
    @@ -516,7 +534,7 @@ __resolve_relocs(struct uasm_reloc *rel, struct uasm_label *lab)
    }
    }

    -void __cpuinit
    +void __uasminit
    uasm_resolve_relocs(struct uasm_reloc *rel, struct uasm_label *lab)
    {
    struct uasm_label *l;
    @@ -526,24 +544,27 @@ uasm_resolve_relocs(struct uasm_reloc *rel, struct uasm_label *lab)
    if (rel->lab == l->lab)
    __resolve_relocs(rel, l);
    }
    +UASM_EXPORT_SYMBOL(uasm_resolve_relocs);

    -void __cpuinit
    +void __uasminit
    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;
    }
    +UASM_EXPORT_SYMBOL(uasm_move_relocs);

    -void __cpuinit
    +void __uasminit
    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;
    }
    +UASM_EXPORT_SYMBOL(uasm_move_labels);

    -void __cpuinit
    +void __uasminit
    uasm_copy_handler(struct uasm_reloc *rel, struct uasm_label *lab, u32 *first,
    u32 *end, u32 *target)
    {
    @@ -554,8 +575,9 @@ uasm_copy_handler(struct uasm_reloc *rel, struct uasm_label *lab, u32 *first,
    uasm_move_relocs(rel, first, end, off);
    uasm_move_labels(lab, first, end, off);
    }
    +UASM_EXPORT_SYMBOL(uasm_copy_handler);

    -int __cpuinit uasm_insn_has_bdelay(struct uasm_reloc *rel, u32 *addr)
    +int __uasminit uasm_insn_has_bdelay(struct uasm_reloc *rel, u32 *addr)
    {
    for (; rel->lab != UASM_LABEL_INVALID; rel++) {
    if (rel->addr == addr
    @@ -566,77 +588,88 @@ int __cpuinit uasm_insn_has_bdelay(struct uasm_reloc *rel, u32 *addr)

    return 0;
    }
    +UASM_EXPORT_SYMBOL(uasm_insn_has_bdelay);

    /* Convenience functions for labeled branches. */
    -void __cpuinit
    +void __uasminit
    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);
    }
    +UASM_EXPORT_SYMBOL(uasm_il_bltz);

    -void __cpuinit
    +void __uasminit
    uasm_il_b(u32 **p, struct uasm_reloc **r, int lid)
    {
    uasm_r_mips_pc16(r, *p, lid);
    uasm_i_b(p, 0);
    }
    +UASM_EXPORT_SYMBOL(uasm_il_b);

    -void __cpuinit
    +void __uasminit
    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);
    }
    +UASM_EXPORT_SYMBOL(uasm_il_beqz);

    -void __cpuinit
    +void __uasminit
    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);
    }
    +UASM_EXPORT_SYMBOL(uasm_il_beqzl);

    -void __cpuinit
    +void __uasminit
    uasm_il_bne(u32 **p, struct uasm_reloc **r, unsigned int reg1,
    unsigned int reg2, int lid)
    {
    uasm_r_mips_pc16(r, *p, lid);
    uasm_i_bne(p, reg1, reg2, 0);
    }
    +UASM_EXPORT_SYMBOL(uasm_il_bne);

    -void __cpuinit
    +void __uasminit
    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);
    }
    +UASM_EXPORT_SYMBOL(uasm_il_bnez);

    -void __cpuinit
    +void __uasminit
    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);
    }
    +UASM_EXPORT_SYMBOL(uasm_il_bgezl);

    -void __cpuinit
    +void __uasminit
    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);
    }
    +UASM_EXPORT_SYMBOL(uasm_il_bgez);

    -void __cpuinit
    +void __uasminit
    uasm_il_bbit0(u32 **p, struct uasm_reloc **r, unsigned int reg,
    unsigned int bit, int lid)
    {
    uasm_r_mips_pc16(r, *p, lid);
    uasm_i_bbit0(p, reg, bit, 0);
    }
    +UASM_EXPORT_SYMBOL(uasm_il_bbit0);

    -void __cpuinit
    +void __uasminit
    uasm_il_bbit1(u32 **p, struct uasm_reloc **r, unsigned int reg,
    unsigned int bit, int lid)
    {
    uasm_r_mips_pc16(r, *p, lid);
    uasm_i_bbit1(p, reg, bit, 0);
    }
    +UASM_EXPORT_SYMBOL(uasm_il_bbit1);
    --
    1.7.1.1


    \
     
     \ /
      Last update: 2010-07-24 03:45    [W:0.050 / U:1.224 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site