Merge branch 'mti-next' of git://git.linux-mips.org/pub/scm/sjhill/linux-sjhill into mips-for-linux-next
This commit is contained in:
@@ -296,6 +296,7 @@ symbol = value
|
||||
#define LONG_SUBU subu
|
||||
#define LONG_L lw
|
||||
#define LONG_S sw
|
||||
#define LONG_SP swp
|
||||
#define LONG_SLL sll
|
||||
#define LONG_SLLV sllv
|
||||
#define LONG_SRL srl
|
||||
@@ -318,6 +319,7 @@ symbol = value
|
||||
#define LONG_SUBU dsubu
|
||||
#define LONG_L ld
|
||||
#define LONG_S sd
|
||||
#define LONG_SP sdp
|
||||
#define LONG_SLL dsll
|
||||
#define LONG_SLLV dsllv
|
||||
#define LONG_SRL dsrl
|
||||
|
||||
@@ -11,6 +11,14 @@
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/inst.h>
|
||||
|
||||
extern int __isa_exception_epc(struct pt_regs *regs);
|
||||
extern int __compute_return_epc(struct pt_regs *regs);
|
||||
extern int __compute_return_epc_for_insn(struct pt_regs *regs,
|
||||
union mips_instruction insn);
|
||||
extern int __microMIPS_compute_return_epc(struct pt_regs *regs);
|
||||
extern int __MIPS16e_compute_return_epc(struct pt_regs *regs);
|
||||
|
||||
|
||||
static inline int delay_slot(struct pt_regs *regs)
|
||||
{
|
||||
return regs->cp0_cause & CAUSEF_BD;
|
||||
@@ -18,20 +26,27 @@ static inline int delay_slot(struct pt_regs *regs)
|
||||
|
||||
static inline unsigned long exception_epc(struct pt_regs *regs)
|
||||
{
|
||||
if (!delay_slot(regs))
|
||||
if (likely(!delay_slot(regs)))
|
||||
return regs->cp0_epc;
|
||||
|
||||
if (get_isa16_mode(regs->cp0_epc))
|
||||
return __isa_exception_epc(regs);
|
||||
|
||||
return regs->cp0_epc + 4;
|
||||
}
|
||||
|
||||
#define BRANCH_LIKELY_TAKEN 0x0001
|
||||
|
||||
extern int __compute_return_epc(struct pt_regs *regs);
|
||||
extern int __compute_return_epc_for_insn(struct pt_regs *regs,
|
||||
union mips_instruction insn);
|
||||
|
||||
static inline int compute_return_epc(struct pt_regs *regs)
|
||||
{
|
||||
if (get_isa16_mode(regs->cp0_epc)) {
|
||||
if (cpu_has_mmips)
|
||||
return __microMIPS_compute_return_epc(regs);
|
||||
if (cpu_has_mips16)
|
||||
return __MIPS16e_compute_return_epc(regs);
|
||||
return regs->cp0_epc;
|
||||
}
|
||||
|
||||
if (!delay_slot(regs)) {
|
||||
regs->cp0_epc += 4;
|
||||
return 0;
|
||||
@@ -40,4 +55,19 @@ static inline int compute_return_epc(struct pt_regs *regs)
|
||||
return __compute_return_epc(regs);
|
||||
}
|
||||
|
||||
static inline int MIPS16e_compute_return_epc(struct pt_regs *regs,
|
||||
union mips16e_instruction *inst)
|
||||
{
|
||||
if (likely(!delay_slot(regs))) {
|
||||
if (inst->ri.opcode == MIPS16e_extend_op) {
|
||||
regs->cp0_epc += 4;
|
||||
return 0;
|
||||
}
|
||||
regs->cp0_epc += 2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return __MIPS16e_compute_return_epc(regs);
|
||||
}
|
||||
|
||||
#endif /* _ASM_BRANCH_H */
|
||||
|
||||
15
arch/mips/include/asm/dma-coherence.h
Normal file
15
arch/mips/include/asm/dma-coherence.h
Normal file
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* 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) 2006 Ralf Baechle <ralf@linux-mips.org>
|
||||
*
|
||||
*/
|
||||
#ifndef __ASM_DMA_COHERENCE_H
|
||||
#define __ASM_DMA_COHERENCE_H
|
||||
|
||||
extern int coherentio;
|
||||
extern int hw_coherentio;
|
||||
|
||||
#endif
|
||||
@@ -2,6 +2,7 @@
|
||||
#define _ASM_DMA_MAPPING_H
|
||||
|
||||
#include <asm/scatterlist.h>
|
||||
#include <asm/dma-coherence.h>
|
||||
#include <asm/cache.h>
|
||||
#include <asm-generic/dma-coherent.h>
|
||||
|
||||
|
||||
@@ -54,6 +54,12 @@ do { \
|
||||
extern int mips_dsemul(struct pt_regs *regs, mips_instruction ir,
|
||||
unsigned long cpc);
|
||||
extern int do_dsemulret(struct pt_regs *xcp);
|
||||
extern int fpu_emulator_cop1Handler(struct pt_regs *xcp,
|
||||
struct mips_fpu_struct *ctx, int has_fpu,
|
||||
void *__user *fault_addr);
|
||||
int process_fpemu_return(int sig, void __user *fault_addr);
|
||||
int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
|
||||
unsigned long *contpc);
|
||||
|
||||
/*
|
||||
* Instruction inserted following the badinst to further tag the sequence
|
||||
|
||||
47
arch/mips/include/asm/fw/fw.h
Normal file
47
arch/mips/include/asm/fw/fw.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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) 2012 MIPS Technologies, Inc.
|
||||
*/
|
||||
#ifndef __ASM_FW_H_
|
||||
#define __ASM_FW_H_
|
||||
|
||||
#include <asm/bootinfo.h> /* For cleaner code... */
|
||||
|
||||
enum fw_memtypes {
|
||||
fw_dontuse,
|
||||
fw_code,
|
||||
fw_free,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
unsigned long base; /* Within KSEG0 */
|
||||
unsigned int size; /* bytes */
|
||||
enum fw_memtypes type; /* fw_memtypes */
|
||||
} fw_memblock_t;
|
||||
|
||||
/* Maximum number of memory block descriptors. */
|
||||
#define FW_MAX_MEMBLOCKS 32
|
||||
|
||||
extern int fw_argc;
|
||||
extern int *_fw_argv;
|
||||
extern int *_fw_envp;
|
||||
|
||||
/*
|
||||
* Most firmware like YAMON, PMON, etc. pass arguments and environment
|
||||
* variables as 32-bit pointers. These take care of sign extension.
|
||||
*/
|
||||
#define fw_argv(index) ((char *)(long)_fw_argv[(index)])
|
||||
#define fw_envp(index) ((char *)(long)_fw_envp[(index)])
|
||||
|
||||
extern void fw_init_cmdline(void);
|
||||
extern char *fw_getcmdline(void);
|
||||
extern fw_memblock_t *fw_getmdesc(void);
|
||||
extern void fw_meminit(void);
|
||||
extern char *fw_getenv(char *name);
|
||||
extern unsigned long fw_getenvl(char *name);
|
||||
extern void fw_init_early_console(char port);
|
||||
|
||||
#endif /* __ASM_FW_H_ */
|
||||
@@ -202,7 +202,7 @@
|
||||
#define GIC_VPE_WD_COUNT0_OFS 0x0094
|
||||
#define GIC_VPE_WD_INITIAL0_OFS 0x0098
|
||||
#define GIC_VPE_COMPARE_LO_OFS 0x00a0
|
||||
#define GIC_VPE_COMPARE_HI 0x00a4
|
||||
#define GIC_VPE_COMPARE_HI_OFS 0x00a4
|
||||
|
||||
#define GIC_VPE_EIC_SHADOW_SET_BASE 0x0100
|
||||
#define GIC_VPE_EIC_SS(intr) \
|
||||
@@ -359,7 +359,11 @@ struct gic_shared_intr_map {
|
||||
/* Mapped interrupt to pin X, then GIC will generate the vector (X+1). */
|
||||
#define GIC_PIN_TO_VEC_OFFSET (1)
|
||||
|
||||
extern int gic_present;
|
||||
#include <linux/clocksource.h>
|
||||
#include <linux/irq.h>
|
||||
|
||||
extern unsigned int gic_present;
|
||||
extern unsigned int gic_frequency;
|
||||
extern unsigned long _gic_base;
|
||||
extern unsigned int gic_irq_base;
|
||||
extern unsigned int gic_irq_flags[];
|
||||
@@ -368,18 +372,20 @@ extern struct gic_shared_intr_map gic_shared_intr_map[];
|
||||
extern void gic_init(unsigned long gic_base_addr,
|
||||
unsigned long gic_addrspace_size, struct gic_intr_map *intrmap,
|
||||
unsigned int intrmap_size, unsigned int irqbase);
|
||||
|
||||
extern void gic_clocksource_init(unsigned int);
|
||||
extern unsigned int gic_get_int(void);
|
||||
extern unsigned int gic_compare_int (void);
|
||||
extern cycle_t gic_read_count(void);
|
||||
extern cycle_t gic_read_compare(void);
|
||||
extern void gic_write_compare(cycle_t cnt);
|
||||
extern void gic_send_ipi(unsigned int intr);
|
||||
extern unsigned int plat_ipi_call_int_xlate(unsigned int);
|
||||
extern unsigned int plat_ipi_resched_int_xlate(unsigned int);
|
||||
extern void gic_bind_eic_interrupt(int irq, int set);
|
||||
extern unsigned int gic_get_timer_pending(void);
|
||||
extern unsigned int gic_get_int(void);
|
||||
extern void gic_enable_interrupt(int irq_vec);
|
||||
extern void gic_disable_interrupt(int irq_vec);
|
||||
extern void gic_irq_ack(struct irq_data *d);
|
||||
extern void gic_finish_irq(struct irq_data *d);
|
||||
extern void gic_platform_init(int irqs, struct irq_chip *irq_controller);
|
||||
|
||||
#endif /* _ASM_GICREGS_H */
|
||||
|
||||
@@ -73,4 +73,16 @@
|
||||
|
||||
typedef unsigned int mips_instruction;
|
||||
|
||||
/* microMIPS instruction decode structure. Do NOT export!!! */
|
||||
struct mm_decoded_insn {
|
||||
mips_instruction insn;
|
||||
mips_instruction next_insn;
|
||||
int pc_inc;
|
||||
int next_pc_inc;
|
||||
int micro_mips_mode;
|
||||
};
|
||||
|
||||
/* Recode table from 16-bit register notation to 32-bit GPR. Do NOT export!!! */
|
||||
extern const int reg16to32[];
|
||||
|
||||
#endif /* _ASM_INST_H */
|
||||
|
||||
@@ -336,7 +336,7 @@ enum emulation_result {
|
||||
#define VPN2_MASK 0xffffe000
|
||||
#define TLB_IS_GLOBAL(x) (((x).tlb_lo0 & MIPS3_PG_G) && ((x).tlb_lo1 & MIPS3_PG_G))
|
||||
#define TLB_VPN2(x) ((x).tlb_hi & VPN2_MASK)
|
||||
#define TLB_ASID(x) ((x).tlb_hi & ASID_MASK)
|
||||
#define TLB_ASID(x) (ASID_MASK((x).tlb_hi))
|
||||
#define TLB_IS_VALID(x, va) (((va) & (1 << PAGE_SHIFT)) ? ((x).tlb_lo1 & MIPS3_PG_V) : ((x).tlb_lo0 & MIPS3_PG_V))
|
||||
|
||||
struct kvm_mips_tlb {
|
||||
|
||||
@@ -61,9 +61,8 @@ static inline int plat_device_is_coherent(struct device *dev)
|
||||
{
|
||||
#ifdef CONFIG_DMA_COHERENT
|
||||
return 1;
|
||||
#endif
|
||||
#ifdef CONFIG_DMA_NONCOHERENT
|
||||
return 0;
|
||||
#else
|
||||
return coherentio;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,11 @@
|
||||
/* #define cpu_has_prefetch ? */
|
||||
#define cpu_has_mcheck 1
|
||||
/* #define cpu_has_ejtag ? */
|
||||
#ifdef CONFIG_CPU_MICROMIPS
|
||||
#define cpu_has_llsc 0
|
||||
#else
|
||||
#define cpu_has_llsc 1
|
||||
#endif
|
||||
/* #define cpu_has_vtag_icache ? */
|
||||
/* #define cpu_has_dc_aliases ? */
|
||||
/* #define cpu_has_ic_fills_f_dc ? */
|
||||
|
||||
@@ -83,4 +83,7 @@ extern void mips_pcibios_init(void);
|
||||
#define mips_pcibios_init() do { } while (0)
|
||||
#endif
|
||||
|
||||
extern void mips_scroll_message(void);
|
||||
extern void mips_display_message(const char *str);
|
||||
|
||||
#endif /* __ASM_MIPS_BOARDS_GENERIC_H */
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Carsten Langgaard, carstenl@mips.com
|
||||
* Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
|
||||
*
|
||||
* ########################################################################
|
||||
*
|
||||
* This program is free software; you can distribute it and/or modify it
|
||||
* under the terms of the GNU General Public License (Version 2) as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||
*
|
||||
* ########################################################################
|
||||
*
|
||||
* MIPS boards bootprom interface for the Linux kernel.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _MIPS_PROM_H
|
||||
#define _MIPS_PROM_H
|
||||
|
||||
extern char *prom_getcmdline(void);
|
||||
extern char *prom_getenv(char *name);
|
||||
extern void prom_init_cmdline(void);
|
||||
extern void prom_meminit(void);
|
||||
extern void prom_fixup_mem_map(unsigned long start_mem, unsigned long end_mem);
|
||||
extern void mips_display_message(const char *str);
|
||||
extern void mips_display_word(unsigned int num);
|
||||
extern void mips_scroll_message(void);
|
||||
extern int get_ethernet_addr(char *ethernet_addr);
|
||||
|
||||
/* Memory descriptor management. */
|
||||
#define PROM_MAX_PMEMBLOCKS 32
|
||||
struct prom_pmemblock {
|
||||
unsigned long base; /* Within KSEG0. */
|
||||
unsigned int size; /* In bytes. */
|
||||
unsigned int type; /* free or prom memory */
|
||||
};
|
||||
|
||||
#endif /* !(_MIPS_PROM_H) */
|
||||
@@ -596,6 +596,7 @@
|
||||
#define MIPS_CONF3_RXI (_ULCAST_(1) << 12)
|
||||
#define MIPS_CONF3_ULRI (_ULCAST_(1) << 13)
|
||||
#define MIPS_CONF3_ISA (_ULCAST_(3) << 14)
|
||||
#define MIPS_CONF3_ISA_OE (_ULCAST_(3) << 16)
|
||||
#define MIPS_CONF3_VZ (_ULCAST_(1) << 23)
|
||||
|
||||
#define MIPS_CONF4_MMUSIZEEXT (_ULCAST_(255) << 0)
|
||||
@@ -622,6 +623,24 @@
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/*
|
||||
* Macros for handling the ISA mode bit for microMIPS.
|
||||
*/
|
||||
#define get_isa16_mode(x) ((x) & 0x1)
|
||||
#define msk_isa16_mode(x) ((x) & ~0x1)
|
||||
#define set_isa16_mode(x) do { (x) |= 0x1; } while(0)
|
||||
|
||||
/*
|
||||
* microMIPS instructions can be 16-bit or 32-bit in length. This
|
||||
* returns a 1 if the instruction is 16-bit and a 0 if 32-bit.
|
||||
*/
|
||||
static inline int mm_insn_16bit(u16 insn)
|
||||
{
|
||||
u16 opcode = (insn >> 10) & 0x7;
|
||||
|
||||
return (opcode >= 1 && opcode <= 3) ? 1 : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Functions to access the R10000 performance counters. These are basically
|
||||
* mfc0 and mtc0 instructions from and to coprocessor register with a 5-bit
|
||||
|
||||
@@ -67,45 +67,68 @@ extern unsigned long pgd_current[];
|
||||
TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
|
||||
#endif
|
||||
#endif /* CONFIG_MIPS_PGD_C0_CONTEXT*/
|
||||
#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
|
||||
|
||||
#define ASID_INC 0x40
|
||||
#define ASID_MASK 0xfc0
|
||||
#define ASID_INC(asid) \
|
||||
({ \
|
||||
unsigned long __asid = asid; \
|
||||
__asm__("1:\taddiu\t%0,1\t\t\t\t# patched\n\t" \
|
||||
".section\t__asid_inc,\"a\"\n\t" \
|
||||
".word\t1b\n\t" \
|
||||
".previous" \
|
||||
:"=r" (__asid) \
|
||||
:"0" (__asid)); \
|
||||
__asid; \
|
||||
})
|
||||
#define ASID_MASK(asid) \
|
||||
({ \
|
||||
unsigned long __asid = asid; \
|
||||
__asm__("1:\tandi\t%0,%1,0xfc0\t\t\t# patched\n\t" \
|
||||
".section\t__asid_mask,\"a\"\n\t" \
|
||||
".word\t1b\n\t" \
|
||||
".previous" \
|
||||
:"=r" (__asid) \
|
||||
:"r" (__asid)); \
|
||||
__asid; \
|
||||
})
|
||||
#define ASID_VERSION_MASK \
|
||||
({ \
|
||||
unsigned long __asid; \
|
||||
__asm__("1:\taddiu\t%0,$0,0xff00\t\t\t\t# patched\n\t" \
|
||||
".section\t__asid_version_mask,\"a\"\n\t" \
|
||||
".word\t1b\n\t" \
|
||||
".previous" \
|
||||
:"=r" (__asid)); \
|
||||
__asid; \
|
||||
})
|
||||
#define ASID_FIRST_VERSION \
|
||||
({ \
|
||||
unsigned long __asid = asid; \
|
||||
__asm__("1:\tli\t%0,0x100\t\t\t\t# patched\n\t" \
|
||||
".section\t__asid_first_version,\"a\"\n\t" \
|
||||
".word\t1b\n\t" \
|
||||
".previous" \
|
||||
:"=r" (__asid)); \
|
||||
__asid; \
|
||||
})
|
||||
|
||||
#elif defined(CONFIG_CPU_R8000)
|
||||
|
||||
#define ASID_INC 0x10
|
||||
#define ASID_MASK 0xff0
|
||||
|
||||
#elif defined(CONFIG_MIPS_MT_SMTC)
|
||||
|
||||
#define ASID_INC 0x1
|
||||
extern unsigned long smtc_asid_mask;
|
||||
#define ASID_MASK (smtc_asid_mask)
|
||||
#define HW_ASID_MASK 0xff
|
||||
/* End SMTC/34K debug hack */
|
||||
#else /* FIXME: not correct for R6000 */
|
||||
|
||||
#define ASID_INC 0x1
|
||||
#define ASID_MASK 0xff
|
||||
#define ASID_FIRST_VERSION_R3000 0x1000
|
||||
#define ASID_FIRST_VERSION_R4000 0x100
|
||||
#define ASID_FIRST_VERSION_R8000 0x1000
|
||||
#define ASID_FIRST_VERSION_RM9000 0x1000
|
||||
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
#define SMTC_HW_ASID_MASK 0xff
|
||||
extern unsigned int smtc_asid_mask;
|
||||
#endif
|
||||
|
||||
#define cpu_context(cpu, mm) ((mm)->context.asid[cpu])
|
||||
#define cpu_asid(cpu, mm) (cpu_context((cpu), (mm)) & ASID_MASK)
|
||||
#define cpu_asid(cpu, mm) ASID_MASK(cpu_context((cpu), (mm)))
|
||||
#define asid_cache(cpu) (cpu_data[cpu].asid_cache)
|
||||
|
||||
static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* All unused by hardware upper bits will be considered
|
||||
* as a software asid extension.
|
||||
*/
|
||||
#define ASID_VERSION_MASK ((unsigned long)~(ASID_MASK|(ASID_MASK-1)))
|
||||
#define ASID_FIRST_VERSION ((unsigned long)(~ASID_VERSION_MASK) + 1)
|
||||
|
||||
#ifndef CONFIG_MIPS_MT_SMTC
|
||||
/* Normal, classic MIPS get_new_mmu_context */
|
||||
static inline void
|
||||
@@ -114,7 +137,7 @@ get_new_mmu_context(struct mm_struct *mm, unsigned long cpu)
|
||||
extern void kvm_local_flush_tlb_all(void);
|
||||
unsigned long asid = asid_cache(cpu);
|
||||
|
||||
if (! ((asid += ASID_INC) & ASID_MASK) ) {
|
||||
if (!ASID_MASK((asid = ASID_INC(asid)))) {
|
||||
if (cpu_has_vtag_icache)
|
||||
flush_icache_all();
|
||||
#ifdef CONFIG_VIRTUALIZATION
|
||||
@@ -177,7 +200,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
|
||||
* free up the ASID value for use and flush any old
|
||||
* instances of it from the TLB.
|
||||
*/
|
||||
oldasid = (read_c0_entryhi() & ASID_MASK);
|
||||
oldasid = ASID_MASK(read_c0_entryhi());
|
||||
if(smtc_live_asid[mytlb][oldasid]) {
|
||||
smtc_live_asid[mytlb][oldasid] &= ~(0x1 << cpu);
|
||||
if(smtc_live_asid[mytlb][oldasid] == 0)
|
||||
@@ -188,7 +211,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
|
||||
* having ASID_MASK smaller than the hardware maximum,
|
||||
* make sure no "soft" bits become "hard"...
|
||||
*/
|
||||
write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK) |
|
||||
write_c0_entryhi((read_c0_entryhi() & ~SMTC_HW_ASID_MASK) |
|
||||
cpu_asid(cpu, next));
|
||||
ehb(); /* Make sure it propagates to TCStatus */
|
||||
evpe(mtflags);
|
||||
@@ -241,15 +264,15 @@ activate_mm(struct mm_struct *prev, struct mm_struct *next)
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
/* See comments for similar code above */
|
||||
mtflags = dvpe();
|
||||
oldasid = read_c0_entryhi() & ASID_MASK;
|
||||
oldasid = ASID_MASK(read_c0_entryhi());
|
||||
if(smtc_live_asid[mytlb][oldasid]) {
|
||||
smtc_live_asid[mytlb][oldasid] &= ~(0x1 << cpu);
|
||||
if(smtc_live_asid[mytlb][oldasid] == 0)
|
||||
smtc_flush_tlb_asid(oldasid);
|
||||
}
|
||||
/* See comments for similar code above */
|
||||
write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK) |
|
||||
cpu_asid(cpu, next));
|
||||
write_c0_entryhi((read_c0_entryhi() & ~SMTC_HW_ASID_MASK) |
|
||||
cpu_asid(cpu, next));
|
||||
ehb(); /* Make sure it propagates to TCStatus */
|
||||
evpe(mtflags);
|
||||
#else
|
||||
@@ -286,14 +309,14 @@ drop_mmu_context(struct mm_struct *mm, unsigned cpu)
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
/* See comments for similar code above */
|
||||
prevvpe = dvpe();
|
||||
oldasid = (read_c0_entryhi() & ASID_MASK);
|
||||
oldasid = ASID_MASK(read_c0_entryhi());
|
||||
if (smtc_live_asid[mytlb][oldasid]) {
|
||||
smtc_live_asid[mytlb][oldasid] &= ~(0x1 << cpu);
|
||||
if(smtc_live_asid[mytlb][oldasid] == 0)
|
||||
smtc_flush_tlb_asid(oldasid);
|
||||
}
|
||||
/* See comments for similar code above */
|
||||
write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK)
|
||||
write_c0_entryhi((read_c0_entryhi() & ~SMTC_HW_ASID_MASK)
|
||||
| cpu_asid(cpu, mm));
|
||||
ehb(); /* Make sure it propagates to TCStatus */
|
||||
evpe(prevvpe);
|
||||
|
||||
@@ -139,7 +139,7 @@
|
||||
1: move ra, k0
|
||||
li k0, 3
|
||||
mtc0 k0, $22
|
||||
#endif /* CONFIG_CPU_LOONGSON2F */
|
||||
#endif /* CONFIG_CPU_JUMP_WORKAROUNDS */
|
||||
#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
|
||||
lui k1, %hi(kernelsp)
|
||||
#else
|
||||
@@ -189,6 +189,7 @@
|
||||
LONG_S $0, PT_R0(sp)
|
||||
mfc0 v1, CP0_STATUS
|
||||
LONG_S $2, PT_R2(sp)
|
||||
LONG_S v1, PT_STATUS(sp)
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
/*
|
||||
* Ideally, these instructions would be shuffled in
|
||||
@@ -200,21 +201,20 @@
|
||||
LONG_S k0, PT_TCSTATUS(sp)
|
||||
#endif /* CONFIG_MIPS_MT_SMTC */
|
||||
LONG_S $4, PT_R4(sp)
|
||||
LONG_S $5, PT_R5(sp)
|
||||
LONG_S v1, PT_STATUS(sp)
|
||||
mfc0 v1, CP0_CAUSE
|
||||
LONG_S $6, PT_R6(sp)
|
||||
LONG_S $7, PT_R7(sp)
|
||||
LONG_S $5, PT_R5(sp)
|
||||
LONG_S v1, PT_CAUSE(sp)
|
||||
LONG_S $6, PT_R6(sp)
|
||||
MFC0 v1, CP0_EPC
|
||||
LONG_S $7, PT_R7(sp)
|
||||
#ifdef CONFIG_64BIT
|
||||
LONG_S $8, PT_R8(sp)
|
||||
LONG_S $9, PT_R9(sp)
|
||||
#endif
|
||||
LONG_S v1, PT_EPC(sp)
|
||||
LONG_S $25, PT_R25(sp)
|
||||
LONG_S $28, PT_R28(sp)
|
||||
LONG_S $31, PT_R31(sp)
|
||||
LONG_S v1, PT_EPC(sp)
|
||||
ori $28, sp, _THREAD_MASK
|
||||
xori $28, _THREAD_MASK
|
||||
#ifdef CONFIG_CPU_CAVIUM_OCTEON
|
||||
|
||||
@@ -52,13 +52,15 @@ extern int (*perf_irq)(void);
|
||||
*/
|
||||
extern unsigned int __weak get_c0_compare_int(void);
|
||||
extern int r4k_clockevent_init(void);
|
||||
extern int smtc_clockevent_init(void);
|
||||
extern int gic_clockevent_init(void);
|
||||
|
||||
static inline int mips_clockevent_init(void)
|
||||
{
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
extern int smtc_clockevent_init(void);
|
||||
|
||||
return smtc_clockevent_init();
|
||||
#elif defined(CONFIG_CEVT_GIC)
|
||||
return (gic_clockevent_init() | r4k_clockevent_init());
|
||||
#elif defined(CONFIG_CEVT_R4K)
|
||||
return r4k_clockevent_init();
|
||||
#else
|
||||
@@ -69,9 +71,7 @@ static inline int mips_clockevent_init(void)
|
||||
/*
|
||||
* Initialize the count register as a clocksource
|
||||
*/
|
||||
#ifdef CONFIG_CSRC_R4K
|
||||
extern int init_r4k_clocksource(void);
|
||||
#endif
|
||||
|
||||
static inline int init_mips_clocksource(void)
|
||||
{
|
||||
|
||||
@@ -270,6 +270,7 @@ do { \
|
||||
__asm__ __volatile__( \
|
||||
"1: " insn " %1, %3 \n" \
|
||||
"2: \n" \
|
||||
" .insn \n" \
|
||||
" .section .fixup,\"ax\" \n" \
|
||||
"3: li %0, %4 \n" \
|
||||
" j 2b \n" \
|
||||
@@ -296,7 +297,9 @@ do { \
|
||||
__asm__ __volatile__( \
|
||||
"1: lw %1, (%3) \n" \
|
||||
"2: lw %D1, 4(%3) \n" \
|
||||
"3: .section .fixup,\"ax\" \n" \
|
||||
"3: \n" \
|
||||
" .insn \n" \
|
||||
" .section .fixup,\"ax\" \n" \
|
||||
"4: li %0, %4 \n" \
|
||||
" move %1, $0 \n" \
|
||||
" move %D1, $0 \n" \
|
||||
@@ -364,6 +367,7 @@ do { \
|
||||
__asm__ __volatile__( \
|
||||
"1: " insn " %z2, %3 # __put_user_asm\n" \
|
||||
"2: \n" \
|
||||
" .insn \n" \
|
||||
" .section .fixup,\"ax\" \n" \
|
||||
"3: li %0, %4 \n" \
|
||||
" j 2b \n" \
|
||||
@@ -382,6 +386,7 @@ do { \
|
||||
"1: sw %2, (%3) # __put_user_asm_ll32 \n" \
|
||||
"2: sw %D2, 4(%3) \n" \
|
||||
"3: \n" \
|
||||
" .insn \n" \
|
||||
" .section .fixup,\"ax\" \n" \
|
||||
"4: li %0, %4 \n" \
|
||||
" j 3b \n" \
|
||||
@@ -533,6 +538,7 @@ do { \
|
||||
__asm__ __volatile__( \
|
||||
"1: " insn " %1, %3 \n" \
|
||||
"2: \n" \
|
||||
" .insn \n" \
|
||||
" .section .fixup,\"ax\" \n" \
|
||||
"3: li %0, %4 \n" \
|
||||
" j 2b \n" \
|
||||
@@ -558,7 +564,9 @@ do { \
|
||||
"1: ulw %1, (%3) \n" \
|
||||
"2: ulw %D1, 4(%3) \n" \
|
||||
" move %0, $0 \n" \
|
||||
"3: .section .fixup,\"ax\" \n" \
|
||||
"3: \n" \
|
||||
" .insn \n" \
|
||||
" .section .fixup,\"ax\" \n" \
|
||||
"4: li %0, %4 \n" \
|
||||
" move %1, $0 \n" \
|
||||
" move %D1, $0 \n" \
|
||||
@@ -625,6 +633,7 @@ do { \
|
||||
__asm__ __volatile__( \
|
||||
"1: " insn " %z2, %3 # __put_user_unaligned_asm\n" \
|
||||
"2: \n" \
|
||||
" .insn \n" \
|
||||
" .section .fixup,\"ax\" \n" \
|
||||
"3: li %0, %4 \n" \
|
||||
" j 2b \n" \
|
||||
@@ -643,6 +652,7 @@ do { \
|
||||
"1: sw %2, (%3) # __put_user_unaligned_asm_ll32 \n" \
|
||||
"2: sw %D2, 4(%3) \n" \
|
||||
"3: \n" \
|
||||
" .insn \n" \
|
||||
" .section .fixup,\"ax\" \n" \
|
||||
"4: li %0, %4 \n" \
|
||||
" j 3b \n" \
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* Copyright (C) 2004, 2005, 2006, 2008 Thiemo Seufer
|
||||
* Copyright (C) 2005 Maciej W. Rozycki
|
||||
* Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org)
|
||||
* Copyright (C) 2012 MIPS Technologies, Inc.
|
||||
* Copyright (C) 2012, 2013 MIPS Technologies, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
@@ -22,44 +22,75 @@
|
||||
#define UASM_EXPORT_SYMBOL(sym)
|
||||
#endif
|
||||
|
||||
#define _UASM_ISA_CLASSIC 0
|
||||
#define _UASM_ISA_MICROMIPS 1
|
||||
|
||||
#ifndef UASM_ISA
|
||||
#ifdef CONFIG_CPU_MICROMIPS
|
||||
#define UASM_ISA _UASM_ISA_MICROMIPS
|
||||
#else
|
||||
#define UASM_ISA _UASM_ISA_CLASSIC
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (UASM_ISA == _UASM_ISA_CLASSIC)
|
||||
#ifdef CONFIG_CPU_MICROMIPS
|
||||
#define ISAOPC(op) CL_uasm_i##op
|
||||
#define ISAFUNC(x) CL_##x
|
||||
#else
|
||||
#define ISAOPC(op) uasm_i##op
|
||||
#define ISAFUNC(x) x
|
||||
#endif
|
||||
#elif (UASM_ISA == _UASM_ISA_MICROMIPS)
|
||||
#ifdef CONFIG_CPU_MICROMIPS
|
||||
#define ISAOPC(op) uasm_i##op
|
||||
#define ISAFUNC(x) x
|
||||
#else
|
||||
#define ISAOPC(op) MM_uasm_i##op
|
||||
#define ISAFUNC(x) MM_##x
|
||||
#endif
|
||||
#else
|
||||
#error Unsupported micro-assembler ISA!!!
|
||||
#endif
|
||||
|
||||
#define Ip_u1u2u3(op) \
|
||||
void __uasminit \
|
||||
uasm_i##op(u32 **buf, unsigned int a, unsigned int b, unsigned int c)
|
||||
ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b, unsigned int c)
|
||||
|
||||
#define Ip_u2u1u3(op) \
|
||||
void __uasminit \
|
||||
uasm_i##op(u32 **buf, unsigned int a, unsigned int b, unsigned int c)
|
||||
ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b, unsigned int c)
|
||||
|
||||
#define Ip_u3u1u2(op) \
|
||||
void __uasminit \
|
||||
uasm_i##op(u32 **buf, unsigned int a, unsigned int b, unsigned int c)
|
||||
ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b, unsigned int c)
|
||||
|
||||
#define Ip_u1u2s3(op) \
|
||||
void __uasminit \
|
||||
uasm_i##op(u32 **buf, unsigned int a, unsigned int b, signed int c)
|
||||
ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b, signed int c)
|
||||
|
||||
#define Ip_u2s3u1(op) \
|
||||
void __uasminit \
|
||||
uasm_i##op(u32 **buf, unsigned int a, signed int b, unsigned int c)
|
||||
ISAOPC(op)(u32 **buf, unsigned int a, signed int b, unsigned int c)
|
||||
|
||||
#define Ip_u2u1s3(op) \
|
||||
void __uasminit \
|
||||
uasm_i##op(u32 **buf, unsigned int a, unsigned int b, signed int c)
|
||||
ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b, signed int c)
|
||||
|
||||
#define Ip_u2u1msbu3(op) \
|
||||
void __uasminit \
|
||||
uasm_i##op(u32 **buf, unsigned int a, unsigned int b, unsigned int c, \
|
||||
ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b, unsigned int c, \
|
||||
unsigned int d)
|
||||
|
||||
#define Ip_u1u2(op) \
|
||||
void __uasminit uasm_i##op(u32 **buf, unsigned int a, unsigned int b)
|
||||
void __uasminit ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b)
|
||||
|
||||
#define Ip_u1s2(op) \
|
||||
void __uasminit uasm_i##op(u32 **buf, unsigned int a, signed int b)
|
||||
void __uasminit ISAOPC(op)(u32 **buf, unsigned int a, signed int b)
|
||||
|
||||
#define Ip_u1(op) void __uasminit uasm_i##op(u32 **buf, unsigned int a)
|
||||
#define Ip_u1(op) void __uasminit ISAOPC(op)(u32 **buf, unsigned int a)
|
||||
|
||||
#define Ip_0(op) void __uasminit uasm_i##op(u32 **buf)
|
||||
#define Ip_0(op) void __uasminit ISAOPC(op)(u32 **buf)
|
||||
|
||||
Ip_u2u1s3(_addiu);
|
||||
Ip_u3u1u2(_addu);
|
||||
@@ -132,19 +163,20 @@ struct uasm_label {
|
||||
int lab;
|
||||
};
|
||||
|
||||
void __uasminit uasm_build_label(struct uasm_label **lab, u32 *addr, int lid);
|
||||
void __uasminit ISAFUNC(uasm_build_label)(struct uasm_label **lab, u32 *addr,
|
||||
int lid);
|
||||
#ifdef CONFIG_64BIT
|
||||
int uasm_in_compat_space_p(long addr);
|
||||
int ISAFUNC(uasm_in_compat_space_p)(long addr);
|
||||
#endif
|
||||
int uasm_rel_hi(long val);
|
||||
int uasm_rel_lo(long val);
|
||||
void UASM_i_LA_mostly(u32 **buf, unsigned int rs, long addr);
|
||||
void UASM_i_LA(u32 **buf, unsigned int rs, long addr);
|
||||
int ISAFUNC(uasm_rel_hi)(long val);
|
||||
int ISAFUNC(uasm_rel_lo)(long val);
|
||||
void ISAFUNC(UASM_i_LA_mostly)(u32 **buf, unsigned int rs, long addr);
|
||||
void ISAFUNC(UASM_i_LA)(u32 **buf, unsigned int rs, long addr);
|
||||
|
||||
#define UASM_L_LA(lb) \
|
||||
static inline void __uasminit uasm_l##lb(struct uasm_label **lab, u32 *addr) \
|
||||
static inline void __uasminit ISAFUNC(uasm_l##lb)(struct uasm_label **lab, u32 *addr) \
|
||||
{ \
|
||||
uasm_build_label(lab, addr, label##lb); \
|
||||
ISAFUNC(uasm_build_label)(lab, addr, label##lb); \
|
||||
}
|
||||
|
||||
/* convenience macros for instructions */
|
||||
@@ -196,27 +228,27 @@ static inline void uasm_i_drotr_safe(u32 **p, unsigned int a1,
|
||||
unsigned int a2, unsigned int a3)
|
||||
{
|
||||
if (a3 < 32)
|
||||
uasm_i_drotr(p, a1, a2, a3);
|
||||
ISAOPC(_drotr)(p, a1, a2, a3);
|
||||
else
|
||||
uasm_i_drotr32(p, a1, a2, a3 - 32);
|
||||
ISAOPC(_drotr32)(p, a1, a2, a3 - 32);
|
||||
}
|
||||
|
||||
static inline void uasm_i_dsll_safe(u32 **p, unsigned int a1,
|
||||
unsigned int a2, unsigned int a3)
|
||||
{
|
||||
if (a3 < 32)
|
||||
uasm_i_dsll(p, a1, a2, a3);
|
||||
ISAOPC(_dsll)(p, a1, a2, a3);
|
||||
else
|
||||
uasm_i_dsll32(p, a1, a2, a3 - 32);
|
||||
ISAOPC(_dsll32)(p, a1, a2, a3 - 32);
|
||||
}
|
||||
|
||||
static inline void uasm_i_dsrl_safe(u32 **p, unsigned int a1,
|
||||
unsigned int a2, unsigned int a3)
|
||||
{
|
||||
if (a3 < 32)
|
||||
uasm_i_dsrl(p, a1, a2, a3);
|
||||
ISAOPC(_dsrl)(p, a1, a2, a3);
|
||||
else
|
||||
uasm_i_dsrl32(p, a1, a2, a3 - 32);
|
||||
ISAOPC(_dsrl32)(p, a1, a2, a3 - 32);
|
||||
}
|
||||
|
||||
/* Handle relocations. */
|
||||
|
||||
Reference in New Issue
Block a user