Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus
Pull MIPS updates from Ralf Baechle: - three fixes for 3.15 that didn't make it in time - limited Octeon 3 support. - paravirtualization support - improvment to platform support for Netlogix SOCs. - add support for powering down the Malta eval board in software - add many instructions to the in-kernel microassembler. - add support for the BPF JIT. - minor cleanups of the BCM47xx code. - large cleanup of math emu code resulting in significant code size reduction, better readability of the code and more accurate emulation. - improvments to the MIPS CPS code. - support C3 power status for the R4k count/compare clock device. - improvments to the GIO support for older SGI workstations. - increase number of supported CPUs to 256; this can be reached on certain embedded multithreaded ccNUMA configurations. - various small cleanups, updates and fixes * 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (173 commits) MIPS: IP22/IP28: Improve GIO support MIPS: Octeon: Add twsi interrupt initialization for OCTEON 3XXX, 5XXX, 63XX DEC: Document the R4k MB ASIC mini interrupt controller DEC: Add self as the maintainer MIPS: Add microMIPS MSA support. MIPS: Replace calls to obsolete strict_strto call with kstrto* equivalents. MIPS: Replace obsolete strict_strto call with kstrto MIPS: BFP: Simplify code slightly. MIPS: Call find_vma with the mmap_sem held MIPS: Fix 'write_msa_##' inline macro. MIPS: Fix MSA toolchain support detection. mips: Update the email address of Geert Uytterhoeven MIPS: Add minimal defconfig for mips_paravirt MIPS: Enable build for new system 'paravirt' MIPS: paravirt: Add pci controller for virtio MIPS: Add code for new system 'paravirt' MIPS: Add functions for hypervisor call MIPS: OCTEON: Add OCTEON3 to __get_cpu_type MIPS: Add function get_ebase_cpunum MIPS: Add minimal support for OCTEON3 to c-r4k.c ...
This commit is contained in:
@@ -17,26 +17,8 @@
|
||||
#ifdef CONFIG_64BIT
|
||||
#include <asm/asmmacro-64.h>
|
||||
#endif
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
#include <asm/mipsmtregs.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
.macro local_irq_enable reg=t0
|
||||
mfc0 \reg, CP0_TCSTATUS
|
||||
ori \reg, \reg, TCSTATUS_IXMT
|
||||
xori \reg, \reg, TCSTATUS_IXMT
|
||||
mtc0 \reg, CP0_TCSTATUS
|
||||
_ehb
|
||||
.endm
|
||||
|
||||
.macro local_irq_disable reg=t0
|
||||
mfc0 \reg, CP0_TCSTATUS
|
||||
ori \reg, \reg, TCSTATUS_IXMT
|
||||
mtc0 \reg, CP0_TCSTATUS
|
||||
_ehb
|
||||
.endm
|
||||
#elif defined(CONFIG_CPU_MIPSR2)
|
||||
#ifdef CONFIG_CPU_MIPSR2
|
||||
.macro local_irq_enable reg=t0
|
||||
ei
|
||||
irq_enable_hazard
|
||||
@@ -71,7 +53,7 @@
|
||||
sw \reg, TI_PRE_COUNT($28)
|
||||
#endif
|
||||
.endm
|
||||
#endif /* CONFIG_MIPS_MT_SMTC */
|
||||
#endif /* CONFIG_CPU_MIPSR2 */
|
||||
|
||||
.macro fpu_save_16even thread tmp=t0
|
||||
cfc1 \tmp, fcr31
|
||||
@@ -267,13 +249,35 @@
|
||||
.set pop
|
||||
.endm
|
||||
#else
|
||||
|
||||
#ifdef CONFIG_CPU_MICROMIPS
|
||||
#define CFC_MSA_INSN 0x587e0056
|
||||
#define CTC_MSA_INSN 0x583e0816
|
||||
#define LDD_MSA_INSN 0x58000837
|
||||
#define STD_MSA_INSN 0x5800083f
|
||||
#define COPY_UW_MSA_INSN 0x58f00056
|
||||
#define COPY_UD_MSA_INSN 0x58f80056
|
||||
#define INSERT_W_MSA_INSN 0x59300816
|
||||
#define INSERT_D_MSA_INSN 0x59380816
|
||||
#else
|
||||
#define CFC_MSA_INSN 0x787e0059
|
||||
#define CTC_MSA_INSN 0x783e0819
|
||||
#define LDD_MSA_INSN 0x78000823
|
||||
#define STD_MSA_INSN 0x78000827
|
||||
#define COPY_UW_MSA_INSN 0x78f00059
|
||||
#define COPY_UD_MSA_INSN 0x78f80059
|
||||
#define INSERT_W_MSA_INSN 0x79300819
|
||||
#define INSERT_D_MSA_INSN 0x79380819
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Temporary until all toolchains in use include MSA support.
|
||||
*/
|
||||
.macro cfcmsa rd, cs
|
||||
.set push
|
||||
.set noat
|
||||
.word 0x787e0059 | (\cs << 11)
|
||||
.insn
|
||||
.word CFC_MSA_INSN | (\cs << 11)
|
||||
move \rd, $1
|
||||
.set pop
|
||||
.endm
|
||||
@@ -282,7 +286,7 @@
|
||||
.set push
|
||||
.set noat
|
||||
move $1, \rs
|
||||
.word 0x783e0819 | (\cd << 6)
|
||||
.word CTC_MSA_INSN | (\cd << 6)
|
||||
.set pop
|
||||
.endm
|
||||
|
||||
@@ -290,7 +294,7 @@
|
||||
.set push
|
||||
.set noat
|
||||
add $1, \base, \off
|
||||
.word 0x78000823 | (\wd << 6)
|
||||
.word LDD_MSA_INSN | (\wd << 6)
|
||||
.set pop
|
||||
.endm
|
||||
|
||||
@@ -298,14 +302,15 @@
|
||||
.set push
|
||||
.set noat
|
||||
add $1, \base, \off
|
||||
.word 0x78000827 | (\wd << 6)
|
||||
.word STD_MSA_INSN | (\wd << 6)
|
||||
.set pop
|
||||
.endm
|
||||
|
||||
.macro copy_u_w rd, ws, n
|
||||
.set push
|
||||
.set noat
|
||||
.word 0x78f00059 | (\n << 16) | (\ws << 11)
|
||||
.insn
|
||||
.word COPY_UW_MSA_INSN | (\n << 16) | (\ws << 11)
|
||||
/* move triggers an assembler bug... */
|
||||
or \rd, $1, zero
|
||||
.set pop
|
||||
@@ -314,7 +319,8 @@
|
||||
.macro copy_u_d rd, ws, n
|
||||
.set push
|
||||
.set noat
|
||||
.word 0x78f80059 | (\n << 16) | (\ws << 11)
|
||||
.insn
|
||||
.word COPY_UD_MSA_INSN | (\n << 16) | (\ws << 11)
|
||||
/* move triggers an assembler bug... */
|
||||
or \rd, $1, zero
|
||||
.set pop
|
||||
@@ -325,7 +331,7 @@
|
||||
.set noat
|
||||
/* move triggers an assembler bug... */
|
||||
or $1, \rs, zero
|
||||
.word 0x79300819 | (\n << 16) | (\wd << 6)
|
||||
.word INSERT_W_MSA_INSN | (\n << 16) | (\wd << 6)
|
||||
.set pop
|
||||
.endm
|
||||
|
||||
@@ -334,7 +340,7 @@
|
||||
.set noat
|
||||
/* move triggers an assembler bug... */
|
||||
or $1, \rs, zero
|
||||
.word 0x79380819 | (\n << 16) | (\wd << 6)
|
||||
.word INSERT_D_MSA_INSN | (\n << 16) | (\wd << 6)
|
||||
.set pop
|
||||
.endm
|
||||
#endif
|
||||
|
@@ -8,6 +8,8 @@
|
||||
#ifndef _ASM_BRANCH_H
|
||||
#define _ASM_BRANCH_H
|
||||
|
||||
#include <asm/cpu-features.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/inst.h>
|
||||
|
||||
@@ -18,12 +20,40 @@ extern int __compute_return_epc_for_insn(struct pt_regs *regs,
|
||||
extern int __microMIPS_compute_return_epc(struct pt_regs *regs);
|
||||
extern int __MIPS16e_compute_return_epc(struct pt_regs *regs);
|
||||
|
||||
/*
|
||||
* microMIPS bitfields
|
||||
*/
|
||||
#define MM_POOL32A_MINOR_MASK 0x3f
|
||||
#define MM_POOL32A_MINOR_SHIFT 0x6
|
||||
#define MM_MIPS32_COND_FC 0x30
|
||||
|
||||
extern int __mm_isBranchInstr(struct pt_regs *regs,
|
||||
struct mm_decoded_insn dec_insn, unsigned long *contpc);
|
||||
|
||||
static inline int mm_isBranchInstr(struct pt_regs *regs,
|
||||
struct mm_decoded_insn dec_insn, unsigned long *contpc)
|
||||
{
|
||||
if (!cpu_has_mmips)
|
||||
return 0;
|
||||
|
||||
return __mm_isBranchInstr(regs, dec_insn, contpc);
|
||||
}
|
||||
|
||||
static inline int delay_slot(struct pt_regs *regs)
|
||||
{
|
||||
return regs->cp0_cause & CAUSEF_BD;
|
||||
}
|
||||
|
||||
static inline void clear_delay_slot(struct pt_regs *regs)
|
||||
{
|
||||
regs->cp0_cause &= ~CAUSEF_BD;
|
||||
}
|
||||
|
||||
static inline void set_delay_slot(struct pt_regs *regs)
|
||||
{
|
||||
regs->cp0_cause |= CAUSEF_BD;
|
||||
}
|
||||
|
||||
static inline unsigned long exception_epc(struct pt_regs *regs)
|
||||
{
|
||||
if (likely(!delay_slot(regs)))
|
||||
|
@@ -113,6 +113,12 @@ unsigned long run_uncached(void *func);
|
||||
|
||||
extern void *kmap_coherent(struct page *page, unsigned long addr);
|
||||
extern void kunmap_coherent(void);
|
||||
extern void *kmap_noncoherent(struct page *page, unsigned long addr);
|
||||
|
||||
static inline void kunmap_noncoherent(void)
|
||||
{
|
||||
kunmap_coherent();
|
||||
}
|
||||
|
||||
#define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE
|
||||
static inline void flush_kernel_dcache_page(struct page *page)
|
||||
|
@@ -10,7 +10,6 @@ extern void cmp_smp_setup(void);
|
||||
extern void cmp_smp_finish(void);
|
||||
extern void cmp_boot_secondary(int cpu, struct task_struct *t);
|
||||
extern void cmp_init_secondary(void);
|
||||
extern void cmp_cpus_done(void);
|
||||
extern void cmp_prepare_cpus(unsigned int max_cpus);
|
||||
|
||||
/* This is platform specific */
|
||||
|
@@ -110,9 +110,15 @@
|
||||
#ifndef cpu_has_smartmips
|
||||
#define cpu_has_smartmips (cpu_data[0].ases & MIPS_ASE_SMARTMIPS)
|
||||
#endif
|
||||
|
||||
#ifndef cpu_has_rixi
|
||||
#define cpu_has_rixi (cpu_data[0].options & MIPS_CPU_RIXI)
|
||||
# ifdef CONFIG_64BIT
|
||||
# define cpu_has_rixi (cpu_data[0].options & MIPS_CPU_RIXI)
|
||||
# else /* CONFIG_32BIT */
|
||||
# define cpu_has_rixi ((cpu_data[0].options & MIPS_CPU_RIXI) && !cpu_has_64bits)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef cpu_has_mmips
|
||||
# ifdef CONFIG_SYS_SUPPORTS_MICROMIPS
|
||||
# define cpu_has_mmips (cpu_data[0].options & MIPS_CPU_MICROMIPS)
|
||||
@@ -120,6 +126,7 @@
|
||||
# define cpu_has_mmips 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef cpu_has_vtag_icache
|
||||
#define cpu_has_vtag_icache (cpu_data[0].icache.flags & MIPS_CACHE_VTAG)
|
||||
#endif
|
||||
@@ -183,6 +190,17 @@
|
||||
/*
|
||||
* Shortcuts ...
|
||||
*/
|
||||
#define cpu_has_mips_2_3_4_5 (cpu_has_mips_2 | cpu_has_mips_3_4_5)
|
||||
#define cpu_has_mips_3_4_5 (cpu_has_mips_3 | cpu_has_mips_4_5)
|
||||
#define cpu_has_mips_4_5 (cpu_has_mips_4 | cpu_has_mips_5)
|
||||
|
||||
#define cpu_has_mips_2_3_4_5_r (cpu_has_mips_2 | cpu_has_mips_3_4_5_r)
|
||||
#define cpu_has_mips_3_4_5_r (cpu_has_mips_3 | cpu_has_mips_4_5_r)
|
||||
#define cpu_has_mips_4_5_r (cpu_has_mips_4 | cpu_has_mips_5_r)
|
||||
#define cpu_has_mips_5_r (cpu_has_mips_5 | cpu_has_mips_r)
|
||||
|
||||
#define cpu_has_mips_4_5_r2 (cpu_has_mips_4_5 | cpu_has_mips_r2)
|
||||
|
||||
#define cpu_has_mips32 (cpu_has_mips32r1 | cpu_has_mips32r2)
|
||||
#define cpu_has_mips64 (cpu_has_mips64r1 | cpu_has_mips64r2)
|
||||
#define cpu_has_mips_r1 (cpu_has_mips32r1 | cpu_has_mips64r1)
|
||||
|
@@ -65,17 +65,12 @@ struct cpuinfo_mips {
|
||||
#ifdef CONFIG_64BIT
|
||||
int vmbits; /* Virtual memory size in bits */
|
||||
#endif
|
||||
#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_MIPS_MT_SMTC)
|
||||
#ifdef CONFIG_MIPS_MT_SMP
|
||||
/*
|
||||
* In the MIPS MT "SMTC" model, each TC is considered
|
||||
* to be a "CPU" for the purposes of scheduling, but
|
||||
* exception resources, ASID spaces, etc, are common
|
||||
* to all TCs within the same VPE.
|
||||
* There is not necessarily a 1:1 mapping of VPE num to CPU number
|
||||
* in particular on multi-core systems.
|
||||
*/
|
||||
int vpe_id; /* Virtual Processor number */
|
||||
#endif
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
int tc_id; /* Thread Context number */
|
||||
#endif
|
||||
void *data; /* Additional data */
|
||||
unsigned int watch_reg_count; /* Number that exist */
|
||||
@@ -117,7 +112,7 @@ struct proc_cpuinfo_notifier_args {
|
||||
unsigned long n;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_MIPS_MT_SMTC)
|
||||
#ifdef CONFIG_MIPS_MT_SMP
|
||||
# define cpu_vpe_id(cpuinfo) ((cpuinfo)->vpe_id)
|
||||
#else
|
||||
# define cpu_vpe_id(cpuinfo) 0
|
||||
|
@@ -155,9 +155,6 @@ static inline int __pure __get_cpu_type(const int cpu_type)
|
||||
case CPU_RM7000:
|
||||
case CPU_SR71000:
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_HAS_CPU_RM9000
|
||||
case CPU_RM9000:
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_HAS_CPU_SB1
|
||||
case CPU_SB1:
|
||||
case CPU_SB1A:
|
||||
@@ -166,6 +163,7 @@ static inline int __pure __get_cpu_type(const int cpu_type)
|
||||
case CPU_CAVIUM_OCTEON:
|
||||
case CPU_CAVIUM_OCTEON_PLUS:
|
||||
case CPU_CAVIUM_OCTEON2:
|
||||
case CPU_CAVIUM_OCTEON3:
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SYS_HAS_CPU_BMIPS32_3300) || \
|
||||
|
@@ -201,6 +201,7 @@
|
||||
#define PRID_IMP_NETLOGIC_XLP3XX 0x1100
|
||||
#define PRID_IMP_NETLOGIC_XLP2XX 0x1200
|
||||
#define PRID_IMP_NETLOGIC_XLP9XX 0x1500
|
||||
#define PRID_IMP_NETLOGIC_XLP5XX 0x1300
|
||||
|
||||
/*
|
||||
* Particular Revision values for bits 7:0 of the PRId register.
|
||||
@@ -281,7 +282,7 @@ enum cpu_type_enum {
|
||||
CPU_R4700, CPU_R5000, CPU_R5500, CPU_NEVADA, CPU_R5432, CPU_R10000,
|
||||
CPU_R12000, CPU_R14000, CPU_VR41XX, CPU_VR4111, CPU_VR4121, CPU_VR4122,
|
||||
CPU_VR4131, CPU_VR4133, CPU_VR4181, CPU_VR4181A, CPU_RM7000,
|
||||
CPU_SR71000, CPU_RM9000, CPU_TX49XX,
|
||||
CPU_SR71000, CPU_TX49XX,
|
||||
|
||||
/*
|
||||
* R8000 class processors
|
||||
|
@@ -48,13 +48,21 @@
|
||||
#define KN4K_RES_14 (14*IOASIC_SLOT_SIZE) /* unused? */
|
||||
#define KN4K_RES_15 (15*IOASIC_SLOT_SIZE) /* unused? */
|
||||
|
||||
/*
|
||||
* MB ASIC interrupt bits.
|
||||
*/
|
||||
#define KN4K_MB_INR_MB 4 /* ??? */
|
||||
#define KN4K_MB_INR_MT 3 /* memory, I/O bus read/write errors */
|
||||
#define KN4K_MB_INR_RES_2 2 /* unused */
|
||||
#define KN4K_MB_INR_RTC 1 /* RTC */
|
||||
#define KN4K_MB_INR_TC 0 /* I/O ASIC cascade */
|
||||
|
||||
/*
|
||||
* Bits for the MB interrupt register.
|
||||
* The register appears read-only.
|
||||
*/
|
||||
#define KN4K_MB_INT_TC (1<<0) /* TURBOchannel? */
|
||||
#define KN4K_MB_INT_RTC (1<<1) /* RTC? */
|
||||
#define KN4K_MB_INT_MT (1<<3) /* I/O ASIC cascade */
|
||||
#define KN4K_MB_INT_IRQ (0x1f<<0) /* CPU Int[4:0] status. */
|
||||
#define KN4K_MB_INT_IRQ_N(n) (1<<(n)) /* Individual status bits. */
|
||||
|
||||
/*
|
||||
* Bits for the MB control & status register.
|
||||
@@ -70,6 +78,7 @@
|
||||
#define KN4K_MB_CSR_NC (1<<14) /* ??? */
|
||||
#define KN4K_MB_CSR_EE (1<<15) /* (bus) Exception Enable? */
|
||||
#define KN4K_MB_CSR_MSK (0x1f<<16) /* CPU Int[4:0] mask */
|
||||
#define KN4K_MB_CSR_MSK_N(n) (1<<((n)+16)) /* Individual mask bits. */
|
||||
#define KN4K_MB_CSR_FW (1<<21) /* ??? */
|
||||
#define KN4K_MB_CSR_W (1<<31) /* ??? */
|
||||
|
||||
|
@@ -48,11 +48,7 @@
|
||||
enum fixed_addresses {
|
||||
#define FIX_N_COLOURS 8
|
||||
FIX_CMAP_BEGIN,
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
FIX_CMAP_END = FIX_CMAP_BEGIN + (FIX_N_COLOURS * NR_CPUS * 2),
|
||||
#else
|
||||
FIX_CMAP_END = FIX_CMAP_BEGIN + (FIX_N_COLOURS * 2),
|
||||
#endif
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
/* reserved pte's for temporary kernel mappings */
|
||||
FIX_KMAP_BEGIN = FIX_CMAP_END + 1,
|
||||
|
@@ -17,6 +17,7 @@
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/cpu-features.h>
|
||||
#include <asm/fpu_emulator.h>
|
||||
#include <asm/hazards.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/current.h>
|
||||
@@ -28,7 +29,6 @@
|
||||
struct sigcontext;
|
||||
struct sigcontext32;
|
||||
|
||||
extern void fpu_emulator_init_fpu(void);
|
||||
extern void _init_fpu(void);
|
||||
extern void _save_fp(struct task_struct *);
|
||||
extern void _restore_fp(struct task_struct *);
|
||||
@@ -156,15 +156,16 @@ static inline int init_fpu(void)
|
||||
int ret = 0;
|
||||
|
||||
preempt_disable();
|
||||
|
||||
if (cpu_has_fpu) {
|
||||
ret = __own_fpu();
|
||||
if (!ret)
|
||||
_init_fpu();
|
||||
} else {
|
||||
} else
|
||||
fpu_emulator_init_fpu();
|
||||
}
|
||||
|
||||
preempt_enable();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@@ -23,9 +23,12 @@
|
||||
#ifndef _ASM_FPU_EMULATOR_H
|
||||
#define _ASM_FPU_EMULATOR_H
|
||||
|
||||
#include <linux/sched.h>
|
||||
#include <asm/break.h>
|
||||
#include <asm/thread_info.h>
|
||||
#include <asm/inst.h>
|
||||
#include <asm/local.h>
|
||||
#include <asm/processor.h>
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
|
||||
@@ -36,6 +39,11 @@ struct mips_fpu_emulator_stats {
|
||||
local_t cp1ops;
|
||||
local_t cp1xops;
|
||||
local_t errors;
|
||||
local_t ieee754_inexact;
|
||||
local_t ieee754_underflow;
|
||||
local_t ieee754_overflow;
|
||||
local_t ieee754_zerodiv;
|
||||
local_t ieee754_invalidop;
|
||||
};
|
||||
|
||||
DECLARE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats);
|
||||
@@ -71,4 +79,17 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
|
||||
*/
|
||||
#define BREAK_MATH (0x0000000d | (BRK_MEMU << 16))
|
||||
|
||||
#define SIGNALLING_NAN 0x7ff800007ff80000LL
|
||||
|
||||
static inline void fpu_emulator_init_fpu(void)
|
||||
{
|
||||
struct task_struct *t = current;
|
||||
int i;
|
||||
|
||||
t->thread.fpu.fcr31 = 0;
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
set_fpr64(&t->thread.fpu.fpr[i], 0, SIGNALLING_NAN);
|
||||
}
|
||||
|
||||
#endif /* _ASM_FPU_EMULATOR_H */
|
||||
|
@@ -380,6 +380,7 @@ 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_write_cpu_compare(cycle_t cnt, int cpu);
|
||||
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);
|
||||
|
@@ -50,7 +50,7 @@ static inline void gio_device_free(struct gio_device *dev)
|
||||
extern int gio_register_driver(struct gio_driver *);
|
||||
extern void gio_unregister_driver(struct gio_driver *);
|
||||
|
||||
#define gio_get_drvdata(_dev) drv_get_drvdata(&(_dev)->dev)
|
||||
#define gio_set_drvdata(_dev, data) drv_set_drvdata(&(_dev)->dev, (data))
|
||||
#define gio_get_drvdata(_dev) dev_get_drvdata(&(_dev)->dev)
|
||||
#define gio_set_drvdata(_dev, data) dev_set_drvdata(&(_dev)->dev, (data))
|
||||
|
||||
extern void gio_set_master(struct gio_device *);
|
||||
|
@@ -1,6 +1,7 @@
|
||||
#ifndef __ASM_IDLE_H
|
||||
#define __ASM_IDLE_H
|
||||
|
||||
#include <linux/cpuidle.h>
|
||||
#include <linux/linkage.h>
|
||||
|
||||
extern void (*cpu_wait)(void);
|
||||
@@ -20,4 +21,17 @@ static inline int address_is_in_r4k_wait_irqoff(unsigned long addr)
|
||||
addr < (unsigned long)__pastwait;
|
||||
}
|
||||
|
||||
extern int mips_cpuidle_wait_enter(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv, int index);
|
||||
|
||||
#define MIPS_CPUIDLE_WAIT_STATE {\
|
||||
.enter = mips_cpuidle_wait_enter,\
|
||||
.exit_latency = 1,\
|
||||
.target_residency = 1,\
|
||||
.power_usage = UINT_MAX,\
|
||||
.flags = CPUIDLE_FLAG_TIME_VALID,\
|
||||
.name = "wait",\
|
||||
.desc = "MIPS wait",\
|
||||
}
|
||||
|
||||
#endif /* __ASM_IDLE_H */
|
||||
|
@@ -26,104 +26,8 @@ static inline int irq_canonicalize(int irq)
|
||||
#define irq_canonicalize(irq) (irq) /* Sane hardware, sane code ... */
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
|
||||
struct irqaction;
|
||||
|
||||
extern unsigned long irq_hwmask[];
|
||||
extern int setup_irq_smtc(unsigned int irq, struct irqaction * new,
|
||||
unsigned long hwmask);
|
||||
|
||||
static inline void smtc_im_ack_irq(unsigned int irq)
|
||||
{
|
||||
if (irq_hwmask[irq] & ST0_IM)
|
||||
set_c0_status(irq_hwmask[irq] & ST0_IM);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static inline void smtc_im_ack_irq(unsigned int irq)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* CONFIG_MIPS_MT_SMTC */
|
||||
|
||||
#ifdef CONFIG_MIPS_MT_SMTC_IRQAFF
|
||||
#include <linux/cpumask.h>
|
||||
|
||||
extern int plat_set_irq_affinity(struct irq_data *d,
|
||||
const struct cpumask *affinity, bool force);
|
||||
extern void smtc_forward_irq(struct irq_data *d);
|
||||
|
||||
/*
|
||||
* IRQ affinity hook invoked at the beginning of interrupt dispatch
|
||||
* if option is enabled.
|
||||
*
|
||||
* Up through Linux 2.6.22 (at least) cpumask operations are very
|
||||
* inefficient on MIPS. Initial prototypes of SMTC IRQ affinity
|
||||
* used a "fast path" per-IRQ-descriptor cache of affinity information
|
||||
* to reduce latency. As there is a project afoot to optimize the
|
||||
* cpumask implementations, this version is optimistically assuming
|
||||
* that cpumask.h macro overhead is reasonable during interrupt dispatch.
|
||||
*/
|
||||
static inline int handle_on_other_cpu(unsigned int irq)
|
||||
{
|
||||
struct irq_data *d = irq_get_irq_data(irq);
|
||||
|
||||
if (cpumask_test_cpu(smp_processor_id(), d->affinity))
|
||||
return 0;
|
||||
smtc_forward_irq(d);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#else /* Not doing SMTC affinity */
|
||||
|
||||
static inline int handle_on_other_cpu(unsigned int irq) { return 0; }
|
||||
|
||||
#endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */
|
||||
|
||||
#ifdef CONFIG_MIPS_MT_SMTC_IM_BACKSTOP
|
||||
|
||||
static inline void smtc_im_backstop(unsigned int irq)
|
||||
{
|
||||
if (irq_hwmask[irq] & 0x0000ff00)
|
||||
write_c0_tccontext(read_c0_tccontext() &
|
||||
~(irq_hwmask[irq] & 0x0000ff00));
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear interrupt mask handling "backstop" if irq_hwmask
|
||||
* entry so indicates. This implies that the ack() or end()
|
||||
* functions will take over re-enabling the low-level mask.
|
||||
* Otherwise it will be done on return from exception.
|
||||
*/
|
||||
static inline int smtc_handle_on_other_cpu(unsigned int irq)
|
||||
{
|
||||
int ret = handle_on_other_cpu(irq);
|
||||
|
||||
if (!ret)
|
||||
smtc_im_backstop(irq);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static inline void smtc_im_backstop(unsigned int irq) { }
|
||||
static inline int smtc_handle_on_other_cpu(unsigned int irq)
|
||||
{
|
||||
return handle_on_other_cpu(irq);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
extern void do_IRQ(unsigned int irq);
|
||||
|
||||
#ifdef CONFIG_MIPS_MT_SMTC_IRQAFF
|
||||
|
||||
extern void do_IRQ_no_affinity(unsigned int irq);
|
||||
|
||||
#endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */
|
||||
|
||||
extern void arch_init_irq(void);
|
||||
extern void spurious_interrupt(void);
|
||||
|
||||
|
@@ -17,7 +17,7 @@
|
||||
#include <linux/stringify.h>
|
||||
#include <asm/hazards.h>
|
||||
|
||||
#if defined(CONFIG_CPU_MIPSR2) && !defined(CONFIG_MIPS_MT_SMTC)
|
||||
#ifdef CONFIG_CPU_MIPSR2
|
||||
|
||||
static inline void arch_local_irq_disable(void)
|
||||
{
|
||||
@@ -118,30 +118,15 @@ void arch_local_irq_disable(void);
|
||||
unsigned long arch_local_irq_save(void);
|
||||
void arch_local_irq_restore(unsigned long flags);
|
||||
void __arch_local_irq_restore(unsigned long flags);
|
||||
#endif /* if defined(CONFIG_CPU_MIPSR2) && !defined(CONFIG_MIPS_MT_SMTC) */
|
||||
|
||||
|
||||
extern void smtc_ipi_replay(void);
|
||||
#endif /* CONFIG_CPU_MIPSR2 */
|
||||
|
||||
static inline void arch_local_irq_enable(void)
|
||||
{
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
/*
|
||||
* SMTC kernel needs to do a software replay of queued
|
||||
* IPIs, at the cost of call overhead on each local_irq_enable()
|
||||
*/
|
||||
smtc_ipi_replay();
|
||||
#endif
|
||||
__asm__ __volatile__(
|
||||
" .set push \n"
|
||||
" .set reorder \n"
|
||||
" .set noat \n"
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
" mfc0 $1, $2, 1 # SMTC - clear TCStatus.IXMT \n"
|
||||
" ori $1, 0x400 \n"
|
||||
" xori $1, 0x400 \n"
|
||||
" mtc0 $1, $2, 1 \n"
|
||||
#elif defined(CONFIG_CPU_MIPSR2)
|
||||
#if defined(CONFIG_CPU_MIPSR2)
|
||||
" ei \n"
|
||||
#else
|
||||
" mfc0 $1,$12 \n"
|
||||
@@ -163,11 +148,7 @@ static inline unsigned long arch_local_save_flags(void)
|
||||
asm __volatile__(
|
||||
" .set push \n"
|
||||
" .set reorder \n"
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
" mfc0 %[flags], $2, 1 \n"
|
||||
#else
|
||||
" mfc0 %[flags], $12 \n"
|
||||
#endif
|
||||
" .set pop \n"
|
||||
: [flags] "=r" (flags));
|
||||
|
||||
@@ -177,14 +158,7 @@ static inline unsigned long arch_local_save_flags(void)
|
||||
|
||||
static inline int arch_irqs_disabled_flags(unsigned long flags)
|
||||
{
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
/*
|
||||
* SMTC model uses TCStatus.IXMT to disable interrupts for a thread/CPU
|
||||
*/
|
||||
return flags & 0x400;
|
||||
#else
|
||||
return !(flags & 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* #ifndef __ASSEMBLY__ */
|
||||
|
109
arch/mips/include/asm/kvm_para.h
Normal file
109
arch/mips/include/asm/kvm_para.h
Normal file
@@ -0,0 +1,109 @@
|
||||
#ifndef _ASM_MIPS_KVM_PARA_H
|
||||
#define _ASM_MIPS_KVM_PARA_H
|
||||
|
||||
#include <uapi/asm/kvm_para.h>
|
||||
|
||||
#define KVM_HYPERCALL ".word 0x42000028"
|
||||
|
||||
/*
|
||||
* Hypercalls for KVM.
|
||||
*
|
||||
* Hypercall number is passed in v0.
|
||||
* Return value will be placed in v0.
|
||||
* Up to 3 arguments are passed in a0, a1, and a2.
|
||||
*/
|
||||
static inline unsigned long kvm_hypercall0(unsigned long num)
|
||||
{
|
||||
register unsigned long n asm("v0");
|
||||
register unsigned long r asm("v0");
|
||||
|
||||
n = num;
|
||||
__asm__ __volatile__(
|
||||
KVM_HYPERCALL
|
||||
: "=r" (r) : "r" (n) : "memory"
|
||||
);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static inline unsigned long kvm_hypercall1(unsigned long num,
|
||||
unsigned long arg0)
|
||||
{
|
||||
register unsigned long n asm("v0");
|
||||
register unsigned long r asm("v0");
|
||||
register unsigned long a0 asm("a0");
|
||||
|
||||
n = num;
|
||||
a0 = arg0;
|
||||
__asm__ __volatile__(
|
||||
KVM_HYPERCALL
|
||||
: "=r" (r) : "r" (n), "r" (a0) : "memory"
|
||||
);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static inline unsigned long kvm_hypercall2(unsigned long num,
|
||||
unsigned long arg0, unsigned long arg1)
|
||||
{
|
||||
register unsigned long n asm("v0");
|
||||
register unsigned long r asm("v0");
|
||||
register unsigned long a0 asm("a0");
|
||||
register unsigned long a1 asm("a1");
|
||||
|
||||
n = num;
|
||||
a0 = arg0;
|
||||
a1 = arg1;
|
||||
__asm__ __volatile__(
|
||||
KVM_HYPERCALL
|
||||
: "=r" (r) : "r" (n), "r" (a0), "r" (a1) : "memory"
|
||||
);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static inline unsigned long kvm_hypercall3(unsigned long num,
|
||||
unsigned long arg0, unsigned long arg1, unsigned long arg2)
|
||||
{
|
||||
register unsigned long n asm("v0");
|
||||
register unsigned long r asm("v0");
|
||||
register unsigned long a0 asm("a0");
|
||||
register unsigned long a1 asm("a1");
|
||||
register unsigned long a2 asm("a2");
|
||||
|
||||
n = num;
|
||||
a0 = arg0;
|
||||
a1 = arg1;
|
||||
a2 = arg2;
|
||||
__asm__ __volatile__(
|
||||
KVM_HYPERCALL
|
||||
: "=r" (r) : "r" (n), "r" (a0), "r" (a1), "r" (a2) : "memory"
|
||||
);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static inline bool kvm_check_and_clear_guest_paused(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline unsigned int kvm_arch_para_features(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MIPS_PARAVIRT
|
||||
static inline bool kvm_para_available(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
static inline bool kvm_para_available(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _ASM_MIPS_KVM_PARA_H */
|
@@ -22,7 +22,6 @@
|
||||
#define cpu_has_3k_cache 0
|
||||
#define cpu_has_4k_cache 0
|
||||
#define cpu_has_tx39_cache 0
|
||||
#define cpu_has_fpu 0
|
||||
#define cpu_has_counter 1
|
||||
#define cpu_has_watch 1
|
||||
#define cpu_has_divec 1
|
||||
|
@@ -35,6 +35,8 @@ enum octeon_irq {
|
||||
OCTEON_IRQ_PCI_MSI2,
|
||||
OCTEON_IRQ_PCI_MSI3,
|
||||
|
||||
OCTEON_IRQ_TWSI,
|
||||
OCTEON_IRQ_TWSI2,
|
||||
OCTEON_IRQ_RML,
|
||||
OCTEON_IRQ_TIMER0,
|
||||
OCTEON_IRQ_TIMER1,
|
||||
|
@@ -39,6 +39,10 @@
|
||||
#define cpu_has_nofpuex 0
|
||||
#define cpu_has_64bits 1
|
||||
|
||||
#define cpu_has_mips_2 1
|
||||
#define cpu_has_mips_3 1
|
||||
#define cpu_has_mips_5 0
|
||||
|
||||
#define cpu_has_mips32r1 0
|
||||
#define cpu_has_mips32r2 0
|
||||
#define cpu_has_mips64r1 0
|
||||
|
@@ -80,36 +80,6 @@
|
||||
.endm
|
||||
|
||||
.macro kernel_entry_setup
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
mfc0 t0, CP0_CONFIG
|
||||
bgez t0, 9f
|
||||
mfc0 t0, CP0_CONFIG, 1
|
||||
bgez t0, 9f
|
||||
mfc0 t0, CP0_CONFIG, 2
|
||||
bgez t0, 9f
|
||||
mfc0 t0, CP0_CONFIG, 3
|
||||
and t0, 1<<2
|
||||
bnez t0, 0f
|
||||
9:
|
||||
/* Assume we came from YAMON... */
|
||||
PTR_LA v0, 0x9fc00534 /* YAMON print */
|
||||
lw v0, (v0)
|
||||
move a0, zero
|
||||
PTR_LA a1, nonmt_processor
|
||||
jal v0
|
||||
|
||||
PTR_LA v0, 0x9fc00520 /* YAMON exit */
|
||||
lw v0, (v0)
|
||||
li a0, 1
|
||||
jal v0
|
||||
|
||||
1: b 1b
|
||||
|
||||
__INITDATA
|
||||
nonmt_processor:
|
||||
.asciz "SMTC kernel requires the MT ASE to run\n"
|
||||
__FINIT
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_EVA
|
||||
sync
|
||||
|
37
arch/mips/include/asm/mach-malta/malta-pm.h
Normal file
37
arch/mips/include/asm/mach-malta/malta-pm.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Imagination Technologies
|
||||
* Author: Paul Burton <paul.burton@imgtec.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef __ASM_MIPS_MACH_MALTA_PM_H__
|
||||
#define __ASM_MIPS_MACH_MALTA_PM_H__
|
||||
|
||||
#include <asm/mips-boards/piix4.h>
|
||||
|
||||
#ifdef CONFIG_MIPS_MALTA_PM
|
||||
|
||||
/**
|
||||
* mips_pm_suspend - enter a suspend state
|
||||
* @state: the state to enter, one of PIIX4_FUNC3IO_PMCNTRL_SUS_TYP_*
|
||||
*
|
||||
* Enters a suspend state via the Malta's PIIX4. If the state to be entered
|
||||
* is one which loses context (eg. SOFF) then this function will never
|
||||
* return.
|
||||
*/
|
||||
extern int mips_pm_suspend(unsigned state);
|
||||
|
||||
#else /* !CONFIG_MIPS_MALTA_PM */
|
||||
|
||||
static inline int mips_pm_suspend(unsigned state)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#endif /* !CONFIG_MIPS_MALTA_PM */
|
||||
|
||||
#endif /* __ASM_MIPS_MACH_MALTA_PM_H__ */
|
@@ -10,10 +10,12 @@
|
||||
|
||||
#include <asm/mach-netlogic/multi-node.h>
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
#define topology_physical_package_id(cpu) cpu_to_node(cpu)
|
||||
#define topology_core_id(cpu) (cpu_logical_map(cpu) / NLM_THREADS_PER_CORE)
|
||||
#define topology_thread_cpumask(cpu) (&cpu_sibling_map[cpu])
|
||||
#define topology_core_cpumask(cpu) cpumask_of_node(cpu_to_node(cpu))
|
||||
#endif
|
||||
|
||||
#include <asm-generic/topology.h>
|
||||
|
||||
|
36
arch/mips/include/asm/mach-paravirt/cpu-feature-overrides.h
Normal file
36
arch/mips/include/asm/mach-paravirt/cpu-feature-overrides.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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) 2013 Cavium, Inc.
|
||||
*/
|
||||
#ifndef __ASM_MACH_PARAVIRT_CPU_FEATURE_OVERRIDES_H
|
||||
#define __ASM_MACH_PARAVIRT_CPU_FEATURE_OVERRIDES_H
|
||||
|
||||
#define cpu_has_4kex 1
|
||||
#define cpu_has_3k_cache 0
|
||||
#define cpu_has_tx39_cache 0
|
||||
#define cpu_has_counter 1
|
||||
#define cpu_has_llsc 1
|
||||
/*
|
||||
* We Disable LL/SC on non SMP systems as it is faster to disable
|
||||
* interrupts for atomic access than a LL/SC.
|
||||
*/
|
||||
#ifdef CONFIG_SMP
|
||||
# define kernel_uses_llsc 1
|
||||
#else
|
||||
# define kernel_uses_llsc 0
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CPU_CAVIUM_OCTEON
|
||||
#define cpu_dcache_line_size() 128
|
||||
#define cpu_icache_line_size() 128
|
||||
#define cpu_has_octeon_cache 1
|
||||
#define cpu_has_4k_cache 0
|
||||
#else
|
||||
#define cpu_has_octeon_cache 0
|
||||
#define cpu_has_4k_cache 1
|
||||
#endif
|
||||
|
||||
#endif /* __ASM_MACH_PARAVIRT_CPU_FEATURE_OVERRIDES_H */
|
19
arch/mips/include/asm/mach-paravirt/irq.h
Normal file
19
arch/mips/include/asm/mach-paravirt/irq.h
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* 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) 2013 Cavium, Inc.
|
||||
*/
|
||||
#ifndef __ASM_MACH_PARAVIRT_IRQ_H__
|
||||
#define __ASM_MACH_PARAVIRT_IRQ_H__
|
||||
|
||||
#define NR_IRQS 64
|
||||
#define MIPS_CPU_IRQ_BASE 1
|
||||
|
||||
#define MIPS_IRQ_PCIA (MIPS_CPU_IRQ_BASE + 8)
|
||||
|
||||
#define MIPS_IRQ_MBOX0 (MIPS_CPU_IRQ_BASE + 32)
|
||||
#define MIPS_IRQ_MBOX1 (MIPS_CPU_IRQ_BASE + 33)
|
||||
|
||||
#endif /* __ASM_MACH_PARAVIRT_IRQ_H__ */
|
50
arch/mips/include/asm/mach-paravirt/kernel-entry-init.h
Normal file
50
arch/mips/include/asm/mach-paravirt/kernel-entry-init.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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) 2013 Cavium, Inc
|
||||
*/
|
||||
#ifndef __ASM_MACH_PARAVIRT_KERNEL_ENTRY_H
|
||||
#define __ASM_MACH_PARAVIRT_KERNEL_ENTRY_H
|
||||
|
||||
#define CP0_EBASE $15, 1
|
||||
|
||||
.macro kernel_entry_setup
|
||||
mfc0 t0, CP0_EBASE
|
||||
andi t0, t0, 0x3ff # CPUNum
|
||||
beqz t0, 1f
|
||||
# CPUs other than zero goto smp_bootstrap
|
||||
j smp_bootstrap
|
||||
|
||||
1:
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Do SMP slave processor setup necessary before we can safely execute
|
||||
* C code.
|
||||
*/
|
||||
.macro smp_slave_setup
|
||||
mfc0 t0, CP0_EBASE
|
||||
andi t0, t0, 0x3ff # CPUNum
|
||||
slti t1, t0, NR_CPUS
|
||||
bnez t1, 1f
|
||||
2:
|
||||
di
|
||||
wait
|
||||
b 2b # Unknown CPU, loop forever.
|
||||
1:
|
||||
PTR_LA t1, paravirt_smp_sp
|
||||
PTR_SLL t0, PTR_SCALESHIFT
|
||||
PTR_ADDU t1, t1, t0
|
||||
3:
|
||||
PTR_L sp, 0(t1)
|
||||
beqz sp, 3b # Spin until told to proceed.
|
||||
|
||||
PTR_LA t1, paravirt_smp_gp
|
||||
PTR_ADDU t1, t1, t0
|
||||
sync
|
||||
PTR_L gp, 0(t1)
|
||||
.endm
|
||||
|
||||
#endif /* __ASM_MACH_PARAVIRT_KERNEL_ENTRY_H */
|
25
arch/mips/include/asm/mach-paravirt/war.h
Normal file
25
arch/mips/include/asm/mach-paravirt/war.h
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
|
||||
* Copyright (C) 2013 Cavium Networks <support@caviumnetworks.com>
|
||||
*/
|
||||
#ifndef __ASM_MIPS_MACH_PARAVIRT_WAR_H
|
||||
#define __ASM_MIPS_MACH_PARAVIRT_WAR_H
|
||||
|
||||
#define R4600_V1_INDEX_ICACHEOP_WAR 0
|
||||
#define R4600_V1_HIT_CACHEOP_WAR 0
|
||||
#define R4600_V2_HIT_CACHEOP_WAR 0
|
||||
#define R5432_CP0_INTERRUPT_WAR 0
|
||||
#define BCM1250_M3_WAR 0
|
||||
#define SIBYTE_1956_WAR 0
|
||||
#define MIPS4K_ICACHE_REFILL_WAR 0
|
||||
#define MIPS_CACHE_SYNC_WAR 0
|
||||
#define TX49XX_ICACHE_INDEX_INV_WAR 0
|
||||
#define ICACHE_REFILLS_WORKAROUND_WAR 0
|
||||
#define R10000_LLSC_WAR 0
|
||||
#define MIPS34K_MISSED_ITLB_WAR 0
|
||||
|
||||
#endif /* __ASM_MIPS_MACH_PARAVIRT_WAR_H */
|
@@ -25,11 +25,7 @@
|
||||
#ifndef MSP_USB_H_
|
||||
#define MSP_USB_H_
|
||||
|
||||
#ifdef CONFIG_MSP_HAS_DUAL_USB
|
||||
#define NUM_USB_DEVS 2
|
||||
#else
|
||||
#define NUM_USB_DEVS 1
|
||||
#endif
|
||||
|
||||
/* Register spaces for USB host 0 */
|
||||
#define MSP_USB0_MAB_START (MSP_USB0_BASE + 0x0)
|
||||
|
@@ -17,7 +17,6 @@
|
||||
#define MIPS4K_ICACHE_REFILL_WAR 0
|
||||
#define MIPS_CACHE_SYNC_WAR 0
|
||||
#define TX49XX_ICACHE_INDEX_INV_WAR 0
|
||||
#define RM9000_CDEX_SMP_WAR 0
|
||||
#define ICACHE_REFILLS_WORKAROUND_WAR 0
|
||||
#define R10000_LLSC_WAR 0
|
||||
#define MIPS34K_MISSED_ITLB_WAR 0
|
||||
|
@@ -10,37 +10,6 @@
|
||||
#define __ASM_MACH_MIPS_KERNEL_ENTRY_INIT_H
|
||||
|
||||
.macro kernel_entry_setup
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
mfc0 t0, CP0_CONFIG
|
||||
bgez t0, 9f
|
||||
mfc0 t0, CP0_CONFIG, 1
|
||||
bgez t0, 9f
|
||||
mfc0 t0, CP0_CONFIG, 2
|
||||
bgez t0, 9f
|
||||
mfc0 t0, CP0_CONFIG, 3
|
||||
and t0, 1<<2
|
||||
bnez t0, 0f
|
||||
9 :
|
||||
/* Assume we came from YAMON... */
|
||||
PTR_LA v0, 0x9fc00534 /* YAMON print */
|
||||
lw v0, (v0)
|
||||
move a0, zero
|
||||
PTR_LA a1, nonmt_processor
|
||||
jal v0
|
||||
|
||||
PTR_LA v0, 0x9fc00520 /* YAMON exit */
|
||||
lw v0, (v0)
|
||||
li a0, 1
|
||||
jal v0
|
||||
|
||||
1 : b 1b
|
||||
|
||||
__INITDATA
|
||||
nonmt_processor :
|
||||
.asciz "SMTC kernel requires the MT ASE to run\n"
|
||||
__FINIT
|
||||
0 :
|
||||
#endif
|
||||
.endm
|
||||
|
||||
/*
|
||||
|
@@ -55,4 +55,16 @@
|
||||
#define PIIX4_FUNC3_PMREGMISC 0x80
|
||||
#define PIIX4_FUNC3_PMREGMISC_EN (1 << 0)
|
||||
|
||||
/* Power Management IO Space */
|
||||
#define PIIX4_FUNC3IO_PMSTS 0x00
|
||||
#define PIIX4_FUNC3IO_PMSTS_PWRBTN_STS (1 << 8)
|
||||
#define PIIX4_FUNC3IO_PMCNTRL 0x04
|
||||
#define PIIX4_FUNC3IO_PMCNTRL_SUS_EN (1 << 13)
|
||||
#define PIIX4_FUNC3IO_PMCNTRL_SUS_TYP (0x7 << 10)
|
||||
#define PIIX4_FUNC3IO_PMCNTRL_SUS_TYP_SOFF (0x0 << 10)
|
||||
#define PIIX4_FUNC3IO_PMCNTRL_SUS_TYP_STR (0x1 << 10)
|
||||
|
||||
/* Data for magic special PCI cycle */
|
||||
#define PIIX4_SUSPEND_MAGIC 0x00120002
|
||||
|
||||
#endif /* __ASM_MIPS_BOARDS_PIIX4_H */
|
||||
|
@@ -72,7 +72,12 @@ static inline bool mips_cpc_present(void)
|
||||
#define MIPS_CPC_COCB_OFS 0x4000
|
||||
|
||||
/* Macros to ease the creation of register access functions */
|
||||
#define BUILD_CPC_R_(name, off) \
|
||||
#define BUILD_CPC_R_(name, off) \
|
||||
static inline u32 *addr_cpc_##name(void) \
|
||||
{ \
|
||||
return (u32 *)(mips_cpc_base + (off)); \
|
||||
} \
|
||||
\
|
||||
static inline u32 read_cpc_##name(void) \
|
||||
{ \
|
||||
return __raw_readl(mips_cpc_base + (off)); \
|
||||
@@ -147,4 +152,31 @@ BUILD_CPC_Cx_RW(other, 0x10)
|
||||
#define CPC_Cx_OTHER_CORENUM_SHF 16
|
||||
#define CPC_Cx_OTHER_CORENUM_MSK (_ULCAST_(0xff) << 16)
|
||||
|
||||
#ifdef CONFIG_MIPS_CPC
|
||||
|
||||
/**
|
||||
* mips_cpc_lock_other - lock access to another core
|
||||
* core: the other core to be accessed
|
||||
*
|
||||
* Call before operating upon a core via the 'other' register region in
|
||||
* order to prevent the region being moved during access. Must be followed
|
||||
* by a call to mips_cpc_unlock_other.
|
||||
*/
|
||||
extern void mips_cpc_lock_other(unsigned int core);
|
||||
|
||||
/**
|
||||
* mips_cpc_unlock_other - unlock access to another core
|
||||
*
|
||||
* Call after operating upon another core via the 'other' register region.
|
||||
* Must be called after mips_cpc_lock_other.
|
||||
*/
|
||||
extern void mips_cpc_unlock_other(void);
|
||||
|
||||
#else /* !CONFIG_MIPS_CPC */
|
||||
|
||||
static inline void mips_cpc_lock_other(unsigned int core) { }
|
||||
static inline void mips_cpc_unlock_other(void) { }
|
||||
|
||||
#endif /* !CONFIG_MIPS_CPC */
|
||||
|
||||
#endif /* __MIPS_ASM_MIPS_CPC_H__ */
|
||||
|
@@ -1,7 +1,6 @@
|
||||
/*
|
||||
* Definitions and decalrations for MIPS MT support
|
||||
* that are common between SMTC, VSMP, and/or AP/SP
|
||||
* kernel models.
|
||||
* Definitions and decalrations for MIPS MT support that are common between
|
||||
* the VSMP, and AP/SP kernel models.
|
||||
*/
|
||||
#ifndef __ASM_MIPS_MT_H
|
||||
#define __ASM_MIPS_MT_H
|
||||
|
@@ -36,6 +36,8 @@
|
||||
|
||||
#define read_c0_tcbind() __read_32bit_c0_register($2, 2)
|
||||
|
||||
#define write_c0_tchalt(val) __write_32bit_c0_register($2, 4, val)
|
||||
|
||||
#define read_c0_tccontext() __read_32bit_c0_register($2, 5)
|
||||
#define write_c0_tccontext(val) __write_32bit_c0_register($2, 5, val)
|
||||
|
||||
|
@@ -709,11 +709,18 @@
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/*
|
||||
* Macros for handling the ISA mode bit for microMIPS.
|
||||
* Macros for handling the ISA mode bit for MIPS16 and microMIPS.
|
||||
*/
|
||||
#if defined(CONFIG_SYS_SUPPORTS_MIPS16) || \
|
||||
defined(CONFIG_SYS_SUPPORTS_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)
|
||||
#else
|
||||
#define get_isa16_mode(x) 0
|
||||
#define msk_isa16_mode(x) (x)
|
||||
#define set_isa16_mode(x) do { } while(0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* microMIPS instructions can be 16-bit or 32-bit in length. This
|
||||
@@ -1007,19 +1014,8 @@ do { \
|
||||
#define write_c0_compare3(val) __write_32bit_c0_register($11, 7, val)
|
||||
|
||||
#define read_c0_status() __read_32bit_c0_register($12, 0)
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
#define write_c0_status(val) \
|
||||
do { \
|
||||
__write_32bit_c0_register($12, 0, val); \
|
||||
__ehb(); \
|
||||
} while (0)
|
||||
#else
|
||||
/*
|
||||
* Legacy non-SMTC code, which may be hazardous
|
||||
* but which might not support EHB
|
||||
*/
|
||||
|
||||
#define write_c0_status(val) __write_32bit_c0_register($12, 0, val)
|
||||
#endif /* CONFIG_MIPS_MT_SMTC */
|
||||
|
||||
#define read_c0_cause() __read_32bit_c0_register($13, 0)
|
||||
#define write_c0_cause(val) __write_32bit_c0_register($13, 0, val)
|
||||
@@ -1743,11 +1739,6 @@ static inline void tlb_write_random(void)
|
||||
/*
|
||||
* Manipulate bits in a c0 register.
|
||||
*/
|
||||
#ifndef CONFIG_MIPS_MT_SMTC
|
||||
/*
|
||||
* SMTC Linux requires shutting-down microthread scheduling
|
||||
* during CP0 register read-modify-write sequences.
|
||||
*/
|
||||
#define __BUILD_SET_C0(name) \
|
||||
static inline unsigned int \
|
||||
set_c0_##name(unsigned int set) \
|
||||
@@ -1786,121 +1777,6 @@ change_c0_##name(unsigned int change, unsigned int val) \
|
||||
return res; \
|
||||
}
|
||||
|
||||
#else /* SMTC versions that manage MT scheduling */
|
||||
|
||||
#include <linux/irqflags.h>
|
||||
|
||||
/*
|
||||
* This is a duplicate of dmt() in mipsmtregs.h to avoid problems with
|
||||
* header file recursion.
|
||||
*/
|
||||
static inline unsigned int __dmt(void)
|
||||
{
|
||||
int res;
|
||||
|
||||
__asm__ __volatile__(
|
||||
" .set push \n"
|
||||
" .set mips32r2 \n"
|
||||
" .set noat \n"
|
||||
" .word 0x41610BC1 # dmt $1 \n"
|
||||
" ehb \n"
|
||||
" move %0, $1 \n"
|
||||
" .set pop \n"
|
||||
: "=r" (res));
|
||||
|
||||
instruction_hazard();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#define __VPECONTROL_TE_SHIFT 15
|
||||
#define __VPECONTROL_TE (1UL << __VPECONTROL_TE_SHIFT)
|
||||
|
||||
#define __EMT_ENABLE __VPECONTROL_TE
|
||||
|
||||
static inline void __emt(unsigned int previous)
|
||||
{
|
||||
if ((previous & __EMT_ENABLE))
|
||||
__asm__ __volatile__(
|
||||
" .set mips32r2 \n"
|
||||
" .word 0x41600be1 # emt \n"
|
||||
" ehb \n"
|
||||
" .set mips0 \n");
|
||||
}
|
||||
|
||||
static inline void __ehb(void)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
" .set mips32r2 \n"
|
||||
" ehb \n" " .set mips0 \n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that local_irq_save/restore affect TC-specific IXMT state,
|
||||
* not Status.IE as in non-SMTC kernel.
|
||||
*/
|
||||
|
||||
#define __BUILD_SET_C0(name) \
|
||||
static inline unsigned int \
|
||||
set_c0_##name(unsigned int set) \
|
||||
{ \
|
||||
unsigned int res; \
|
||||
unsigned int new; \
|
||||
unsigned int omt; \
|
||||
unsigned long flags; \
|
||||
\
|
||||
local_irq_save(flags); \
|
||||
omt = __dmt(); \
|
||||
res = read_c0_##name(); \
|
||||
new = res | set; \
|
||||
write_c0_##name(new); \
|
||||
__emt(omt); \
|
||||
local_irq_restore(flags); \
|
||||
\
|
||||
return res; \
|
||||
} \
|
||||
\
|
||||
static inline unsigned int \
|
||||
clear_c0_##name(unsigned int clear) \
|
||||
{ \
|
||||
unsigned int res; \
|
||||
unsigned int new; \
|
||||
unsigned int omt; \
|
||||
unsigned long flags; \
|
||||
\
|
||||
local_irq_save(flags); \
|
||||
omt = __dmt(); \
|
||||
res = read_c0_##name(); \
|
||||
new = res & ~clear; \
|
||||
write_c0_##name(new); \
|
||||
__emt(omt); \
|
||||
local_irq_restore(flags); \
|
||||
\
|
||||
return res; \
|
||||
} \
|
||||
\
|
||||
static inline unsigned int \
|
||||
change_c0_##name(unsigned int change, unsigned int newbits) \
|
||||
{ \
|
||||
unsigned int res; \
|
||||
unsigned int new; \
|
||||
unsigned int omt; \
|
||||
unsigned long flags; \
|
||||
\
|
||||
local_irq_save(flags); \
|
||||
\
|
||||
omt = __dmt(); \
|
||||
res = read_c0_##name(); \
|
||||
new = res & ~change; \
|
||||
new |= (newbits & change); \
|
||||
write_c0_##name(new); \
|
||||
__emt(omt); \
|
||||
local_irq_restore(flags); \
|
||||
\
|
||||
return res; \
|
||||
}
|
||||
#endif
|
||||
|
||||
__BUILD_SET_C0(status)
|
||||
__BUILD_SET_C0(cause)
|
||||
__BUILD_SET_C0(config)
|
||||
@@ -1916,6 +1792,15 @@ __BUILD_SET_C0(brcm_cmt_ctrl)
|
||||
__BUILD_SET_C0(brcm_config)
|
||||
__BUILD_SET_C0(brcm_mode)
|
||||
|
||||
/*
|
||||
* Return low 10 bits of ebase.
|
||||
* Note that under KVM (MIPSVZ) this returns vcpu id.
|
||||
*/
|
||||
static inline unsigned int get_ebase_cpunum(void)
|
||||
{
|
||||
return read_c0_ebase() & 0x3ff;
|
||||
}
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#endif /* _ASM_MIPSREGS_H */
|
||||
|
@@ -18,10 +18,6 @@
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/hazards.h>
|
||||
#include <asm/tlbflush.h>
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
#include <asm/mipsmtregs.h>
|
||||
#include <asm/smtc.h>
|
||||
#endif /* SMTC */
|
||||
#include <asm-generic/mm_hooks.h>
|
||||
|
||||
#define TLBMISS_HANDLER_SETUP_PGD(pgd) \
|
||||
@@ -31,11 +27,15 @@ do { \
|
||||
} while (0)
|
||||
|
||||
#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
|
||||
|
||||
#define TLBMISS_HANDLER_RESTORE() \
|
||||
write_c0_xcontext((unsigned long) smp_processor_id() << \
|
||||
SMP_CPUID_REGSHIFT)
|
||||
|
||||
#define TLBMISS_HANDLER_SETUP() \
|
||||
do { \
|
||||
TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir); \
|
||||
write_c0_xcontext((unsigned long) smp_processor_id() << \
|
||||
SMP_CPUID_REGSHIFT); \
|
||||
TLBMISS_HANDLER_RESTORE(); \
|
||||
} while (0)
|
||||
|
||||
#else /* !CONFIG_MIPS_PGD_C0_CONTEXT: using pgd_current*/
|
||||
@@ -47,9 +47,12 @@ do { \
|
||||
*/
|
||||
extern unsigned long pgd_current[];
|
||||
|
||||
#define TLBMISS_HANDLER_SETUP() \
|
||||
#define TLBMISS_HANDLER_RESTORE() \
|
||||
write_c0_context((unsigned long) smp_processor_id() << \
|
||||
SMP_CPUID_REGSHIFT); \
|
||||
SMP_CPUID_REGSHIFT)
|
||||
|
||||
#define TLBMISS_HANDLER_SETUP() \
|
||||
TLBMISS_HANDLER_RESTORE(); \
|
||||
back_to_back_c0_hazard(); \
|
||||
TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
|
||||
#endif /* CONFIG_MIPS_PGD_C0_CONTEXT*/
|
||||
@@ -63,13 +66,6 @@ extern unsigned long pgd_current[];
|
||||
#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
|
||||
@@ -92,7 +88,6 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
|
||||
#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
|
||||
get_new_mmu_context(struct mm_struct *mm, unsigned long cpu)
|
||||
@@ -115,12 +110,6 @@ get_new_mmu_context(struct mm_struct *mm, unsigned long cpu)
|
||||
cpu_context(cpu, mm) = asid_cache(cpu) = asid;
|
||||
}
|
||||
|
||||
#else /* CONFIG_MIPS_MT_SMTC */
|
||||
|
||||
#define get_new_mmu_context(mm, cpu) smtc_get_new_mmu_context((mm), (cpu))
|
||||
|
||||
#endif /* CONFIG_MIPS_MT_SMTC */
|
||||
|
||||
/*
|
||||
* Initialize the context related info for a new mm_struct
|
||||
* instance.
|
||||
@@ -141,46 +130,12 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
|
||||
{
|
||||
unsigned int cpu = smp_processor_id();
|
||||
unsigned long flags;
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
unsigned long oldasid;
|
||||
unsigned long mtflags;
|
||||
int mytlb = (smtc_status & SMTC_TLB_SHARED) ? 0 : cpu_data[cpu].vpe_id;
|
||||
local_irq_save(flags);
|
||||
mtflags = dvpe();
|
||||
#else /* Not SMTC */
|
||||
local_irq_save(flags);
|
||||
#endif /* CONFIG_MIPS_MT_SMTC */
|
||||
|
||||
/* Check if our ASID is of an older version and thus invalid */
|
||||
if ((cpu_context(cpu, next) ^ asid_cache(cpu)) & ASID_VERSION_MASK)
|
||||
get_new_mmu_context(next, cpu);
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
/*
|
||||
* If the EntryHi ASID being replaced happens to be
|
||||
* the value flagged at ASID recycling time as having
|
||||
* an extended life, clear the bit showing it being
|
||||
* in use by this "CPU", and if that's the last bit,
|
||||
* free up the ASID value for use and flush any old
|
||||
* instances of it from the TLB.
|
||||
*/
|
||||
oldasid = (read_c0_entryhi() & ASID_MASK);
|
||||
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);
|
||||
}
|
||||
/*
|
||||
* Tread softly on EntryHi, and so long as we support
|
||||
* having ASID_MASK smaller than the hardware maximum,
|
||||
* make sure no "soft" bits become "hard"...
|
||||
*/
|
||||
write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK) |
|
||||
cpu_asid(cpu, next));
|
||||
ehb(); /* Make sure it propagates to TCStatus */
|
||||
evpe(mtflags);
|
||||
#else
|
||||
write_c0_entryhi(cpu_asid(cpu, next));
|
||||
#endif /* CONFIG_MIPS_MT_SMTC */
|
||||
TLBMISS_HANDLER_SETUP_PGD(next->pgd);
|
||||
|
||||
/*
|
||||
@@ -213,34 +168,12 @@ activate_mm(struct mm_struct *prev, struct mm_struct *next)
|
||||
unsigned long flags;
|
||||
unsigned int cpu = smp_processor_id();
|
||||
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
unsigned long oldasid;
|
||||
unsigned long mtflags;
|
||||
int mytlb = (smtc_status & SMTC_TLB_SHARED) ? 0 : cpu_data[cpu].vpe_id;
|
||||
#endif /* CONFIG_MIPS_MT_SMTC */
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
/* Unconditionally get a new ASID. */
|
||||
get_new_mmu_context(next, cpu);
|
||||
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
/* See comments for similar code above */
|
||||
mtflags = dvpe();
|
||||
oldasid = read_c0_entryhi() & ASID_MASK;
|
||||
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));
|
||||
ehb(); /* Make sure it propagates to TCStatus */
|
||||
evpe(mtflags);
|
||||
#else
|
||||
write_c0_entryhi(cpu_asid(cpu, next));
|
||||
#endif /* CONFIG_MIPS_MT_SMTC */
|
||||
TLBMISS_HANDLER_SETUP_PGD(next->pgd);
|
||||
|
||||
/* mark mmu ownership change */
|
||||
@@ -258,48 +191,15 @@ static inline void
|
||||
drop_mmu_context(struct mm_struct *mm, unsigned cpu)
|
||||
{
|
||||
unsigned long flags;
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
unsigned long oldasid;
|
||||
/* Can't use spinlock because called from TLB flush within DVPE */
|
||||
unsigned int prevvpe;
|
||||
int mytlb = (smtc_status & SMTC_TLB_SHARED) ? 0 : cpu_data[cpu].vpe_id;
|
||||
#endif /* CONFIG_MIPS_MT_SMTC */
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
if (cpumask_test_cpu(cpu, mm_cpumask(mm))) {
|
||||
get_new_mmu_context(mm, cpu);
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
/* See comments for similar code above */
|
||||
prevvpe = dvpe();
|
||||
oldasid = (read_c0_entryhi() & ASID_MASK);
|
||||
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, mm));
|
||||
ehb(); /* Make sure it propagates to TCStatus */
|
||||
evpe(prevvpe);
|
||||
#else /* not CONFIG_MIPS_MT_SMTC */
|
||||
write_c0_entryhi(cpu_asid(cpu, mm));
|
||||
#endif /* CONFIG_MIPS_MT_SMTC */
|
||||
} else {
|
||||
/* will get a new context next time */
|
||||
#ifndef CONFIG_MIPS_MT_SMTC
|
||||
cpu_context(cpu, mm) = 0;
|
||||
#else /* SMTC */
|
||||
int i;
|
||||
|
||||
/* SMTC shares the TLB (and ASIDs) across VPEs */
|
||||
for_each_online_cpu(i) {
|
||||
if((smtc_status & SMTC_TLB_SHARED)
|
||||
|| (cpu_data[i].vpe_id == cpu_data[cpu].vpe_id))
|
||||
cpu_context(i, mm) = 0;
|
||||
}
|
||||
#endif /* CONFIG_MIPS_MT_SMTC */
|
||||
}
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
@@ -144,13 +144,7 @@ search_module_dbetables(unsigned long addr)
|
||||
#define MODULE_KERNEL_TYPE "64BIT "
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
#define MODULE_KERNEL_SMTC "MT_SMTC "
|
||||
#else
|
||||
#define MODULE_KERNEL_SMTC ""
|
||||
#endif
|
||||
|
||||
#define MODULE_ARCH_VERMAGIC \
|
||||
MODULE_PROC_FAMILY MODULE_KERNEL_TYPE MODULE_KERNEL_SMTC
|
||||
MODULE_PROC_FAMILY MODULE_KERNEL_TYPE
|
||||
|
||||
#endif /* _ASM_MODULE_H */
|
||||
|
@@ -84,7 +84,7 @@ static inline void write_msa_##name(unsigned int val) \
|
||||
__asm__ __volatile__( \
|
||||
" .set push\n" \
|
||||
" .set msa\n" \
|
||||
" cfcmsa $" #cs ", %0\n" \
|
||||
" ctcmsa $" #cs ", %0\n" \
|
||||
" .set pop\n" \
|
||||
: : "r"(val)); \
|
||||
}
|
||||
@@ -96,6 +96,13 @@ static inline void write_msa_##name(unsigned int val) \
|
||||
* allow compilation with toolchains that do not support MSA. Once all
|
||||
* toolchains in use support MSA these can be removed.
|
||||
*/
|
||||
#ifdef CONFIG_CPU_MICROMIPS
|
||||
#define CFC_MSA_INSN 0x587e0056
|
||||
#define CTC_MSA_INSN 0x583e0816
|
||||
#else
|
||||
#define CFC_MSA_INSN 0x787e0059
|
||||
#define CTC_MSA_INSN 0x783e0819
|
||||
#endif
|
||||
|
||||
#define __BUILD_MSA_CTL_REG(name, cs) \
|
||||
static inline unsigned int read_msa_##name(void) \
|
||||
@@ -104,7 +111,8 @@ static inline unsigned int read_msa_##name(void) \
|
||||
__asm__ __volatile__( \
|
||||
" .set push\n" \
|
||||
" .set noat\n" \
|
||||
" .word 0x787e0059 | (" #cs " << 11)\n" \
|
||||
" .insn\n" \
|
||||
" .word #CFC_MSA_INSN | (" #cs " << 11)\n" \
|
||||
" move %0, $1\n" \
|
||||
" .set pop\n" \
|
||||
: "=r"(reg)); \
|
||||
@@ -117,7 +125,8 @@ static inline void write_msa_##name(unsigned int val) \
|
||||
" .set push\n" \
|
||||
" .set noat\n" \
|
||||
" move $1, %0\n" \
|
||||
" .word 0x783e0819 | (" #cs " << 6)\n" \
|
||||
" .insn\n" \
|
||||
" .word #CTC_MSA_INSN | (" #cs " << 6)\n" \
|
||||
" .set pop\n" \
|
||||
: : "r"(val)); \
|
||||
}
|
||||
|
@@ -146,9 +146,10 @@ static inline int hard_smp_processor_id(void)
|
||||
|
||||
static inline int nlm_nodeid(void)
|
||||
{
|
||||
uint32_t prid = read_c0_prid();
|
||||
uint32_t prid = read_c0_prid() & PRID_IMP_MASK;
|
||||
|
||||
if ((prid & 0xff00) == PRID_IMP_NETLOGIC_XLP9XX)
|
||||
if ((prid == PRID_IMP_NETLOGIC_XLP9XX) ||
|
||||
(prid == PRID_IMP_NETLOGIC_XLP5XX))
|
||||
return (__read_32bit_c0_register($15, 1) >> 7) & 0x7;
|
||||
else
|
||||
return (__read_32bit_c0_register($15, 1) >> 5) & 0x3;
|
||||
|
@@ -74,6 +74,8 @@
|
||||
#define XLP_IO_USB_OHCI2_OFFSET(node) XLP_HDR_OFFSET(node, 0, 2, 4)
|
||||
#define XLP_IO_USB_OHCI3_OFFSET(node) XLP_HDR_OFFSET(node, 0, 2, 5)
|
||||
|
||||
#define XLP_IO_SATA_OFFSET(node) XLP_HDR_OFFSET(node, 0, 3, 2)
|
||||
|
||||
/* XLP2xx has an updated USB block */
|
||||
#define XLP2XX_IO_USB_OFFSET(node, i) XLP_HDR_OFFSET(node, 0, 4, i)
|
||||
#define XLP2XX_IO_USB_XHCI0_OFFSET(node) XLP_HDR_OFFSET(node, 0, 4, 1)
|
||||
@@ -103,13 +105,11 @@
|
||||
#define XLP_IO_SYS_OFFSET(node) XLP_HDR_OFFSET(node, 0, 6, 5)
|
||||
#define XLP_IO_JTAG_OFFSET(node) XLP_HDR_OFFSET(node, 0, 6, 6)
|
||||
|
||||
/* Flash */
|
||||
#define XLP_IO_NOR_OFFSET(node) XLP_HDR_OFFSET(node, 0, 7, 0)
|
||||
#define XLP_IO_NAND_OFFSET(node) XLP_HDR_OFFSET(node, 0, 7, 1)
|
||||
#define XLP_IO_SPI_OFFSET(node) XLP_HDR_OFFSET(node, 0, 7, 2)
|
||||
/* SD flash */
|
||||
#define XLP_IO_SD_OFFSET(node) XLP_HDR_OFFSET(node, 0, 7, 3)
|
||||
#define XLP_IO_MMC_OFFSET(node, slot) \
|
||||
((XLP_IO_SD_OFFSET(node))+(slot*0x100)+XLP_IO_PCI_HDRSZ)
|
||||
#define XLP_IO_MMC_OFFSET(node) XLP_HDR_OFFSET(node, 0, 7, 3)
|
||||
|
||||
/* Things have changed drastically in XLP 9XX */
|
||||
#define XLP9XX_HDR_OFFSET(n, d, f) \
|
||||
@@ -120,6 +120,8 @@
|
||||
#define XLP9XX_IO_UART_OFFSET(node) XLP9XX_HDR_OFFSET(node, 2, 2)
|
||||
#define XLP9XX_IO_SYS_OFFSET(node) XLP9XX_HDR_OFFSET(node, 6, 0)
|
||||
#define XLP9XX_IO_FUSE_OFFSET(node) XLP9XX_HDR_OFFSET(node, 6, 1)
|
||||
#define XLP9XX_IO_CLOCK_OFFSET(node) XLP9XX_HDR_OFFSET(node, 6, 2)
|
||||
#define XLP9XX_IO_POWER_OFFSET(node) XLP9XX_HDR_OFFSET(node, 6, 3)
|
||||
#define XLP9XX_IO_JTAG_OFFSET(node) XLP9XX_HDR_OFFSET(node, 6, 4)
|
||||
|
||||
#define XLP9XX_IO_PCIE_OFFSET(node, i) XLP9XX_HDR_OFFSET(node, 1, i)
|
||||
@@ -135,11 +137,11 @@
|
||||
/* XLP9XX on-chip SATA controller */
|
||||
#define XLP9XX_IO_SATA_OFFSET(node) XLP9XX_HDR_OFFSET(node, 3, 2)
|
||||
|
||||
/* Flash */
|
||||
#define XLP9XX_IO_NOR_OFFSET(node) XLP9XX_HDR_OFFSET(node, 7, 0)
|
||||
#define XLP9XX_IO_NAND_OFFSET(node) XLP9XX_HDR_OFFSET(node, 7, 1)
|
||||
#define XLP9XX_IO_SPI_OFFSET(node) XLP9XX_HDR_OFFSET(node, 7, 2)
|
||||
/* SD flash */
|
||||
#define XLP9XX_IO_MMCSD_OFFSET(node) XLP9XX_HDR_OFFSET(node, 7, 3)
|
||||
#define XLP9XX_IO_MMC_OFFSET(node) XLP9XX_HDR_OFFSET(node, 7, 3)
|
||||
|
||||
/* PCI config header register id's */
|
||||
#define XLP_PCI_CFGREG0 0x00
|
||||
@@ -186,8 +188,10 @@
|
||||
#define PCI_DEVICE_ID_NLM_NOR 0x1015
|
||||
#define PCI_DEVICE_ID_NLM_NAND 0x1016
|
||||
#define PCI_DEVICE_ID_NLM_MMC 0x1018
|
||||
#define PCI_DEVICE_ID_NLM_XHCI 0x101d
|
||||
#define PCI_DEVICE_ID_NLM_SATA 0x101A
|
||||
#define PCI_DEVICE_ID_NLM_XHCI 0x101D
|
||||
|
||||
#define PCI_DEVICE_ID_XLP9XX_MMC 0x9018
|
||||
#define PCI_DEVICE_ID_XLP9XX_SATA 0x901A
|
||||
#define PCI_DEVICE_ID_XLP9XX_XHCI 0x901D
|
||||
|
||||
|
@@ -69,6 +69,20 @@
|
||||
#define PCIE_9XX_BYTE_SWAP_IO_BASE 0x25e
|
||||
#define PCIE_9XX_BYTE_SWAP_IO_LIM 0x25f
|
||||
|
||||
#define PCIE_9XX_BRIDGE_MSIX_ADDR_BASE 0x264
|
||||
#define PCIE_9XX_BRIDGE_MSIX_ADDR_LIMIT 0x265
|
||||
#define PCIE_9XX_MSI_STATUS 0x283
|
||||
#define PCIE_9XX_MSI_EN 0x284
|
||||
/* 128 MSIX vectors available in 9xx */
|
||||
#define PCIE_9XX_MSIX_STATUS0 0x286
|
||||
#define PCIE_9XX_MSIX_STATUSX(n) (n + 0x286)
|
||||
#define PCIE_9XX_MSIX_VEC 0x296
|
||||
#define PCIE_9XX_MSIX_VECX(n) (n + 0x296)
|
||||
#define PCIE_9XX_INT_STATUS0 0x397
|
||||
#define PCIE_9XX_INT_STATUS1 0x398
|
||||
#define PCIE_9XX_INT_EN0 0x399
|
||||
#define PCIE_9XX_INT_EN1 0x39a
|
||||
|
||||
/* other */
|
||||
#define PCIE_NLINKS 4
|
||||
|
||||
|
@@ -199,6 +199,10 @@
|
||||
#define PIC_IRT_PCIE_LINK_3_INDEX 81
|
||||
#define PIC_IRT_PCIE_LINK_INDEX(num) ((num) + PIC_IRT_PCIE_LINK_0_INDEX)
|
||||
|
||||
#define PIC_9XX_IRT_PCIE_LINK_0_INDEX 191
|
||||
#define PIC_9XX_IRT_PCIE_LINK_INDEX(num) \
|
||||
((num) + PIC_9XX_IRT_PCIE_LINK_0_INDEX)
|
||||
|
||||
#define PIC_CLOCK_TIMER 7
|
||||
|
||||
#if !defined(LOCORE) && !defined(__ASSEMBLY__)
|
||||
|
@@ -118,6 +118,10 @@
|
||||
#define SYS_SCRTCH3 0x4c
|
||||
|
||||
/* PLL registers XLP2XX */
|
||||
#define SYS_CPU_PLL_CTRL0(core) (0x1c0 + (core * 4))
|
||||
#define SYS_CPU_PLL_CTRL1(core) (0x1c1 + (core * 4))
|
||||
#define SYS_CPU_PLL_CTRL2(core) (0x1c2 + (core * 4))
|
||||
#define SYS_CPU_PLL_CTRL3(core) (0x1c3 + (core * 4))
|
||||
#define SYS_PLL_CTRL0 0x240
|
||||
#define SYS_PLL_CTRL1 0x241
|
||||
#define SYS_PLL_CTRL2 0x242
|
||||
@@ -147,6 +151,32 @@
|
||||
#define SYS_SYS_PLL_MEM_REQ 0x2a3
|
||||
#define SYS_PLL_MEM_STAT 0x2a4
|
||||
|
||||
/* PLL registers XLP9XX */
|
||||
#define SYS_9XX_CPU_PLL_CTRL0(core) (0xc0 + (core * 4))
|
||||
#define SYS_9XX_CPU_PLL_CTRL1(core) (0xc1 + (core * 4))
|
||||
#define SYS_9XX_CPU_PLL_CTRL2(core) (0xc2 + (core * 4))
|
||||
#define SYS_9XX_CPU_PLL_CTRL3(core) (0xc3 + (core * 4))
|
||||
#define SYS_9XX_DMC_PLL_CTRL0 0x140
|
||||
#define SYS_9XX_DMC_PLL_CTRL1 0x141
|
||||
#define SYS_9XX_DMC_PLL_CTRL2 0x142
|
||||
#define SYS_9XX_DMC_PLL_CTRL3 0x143
|
||||
#define SYS_9XX_PLL_CTRL0 0x144
|
||||
#define SYS_9XX_PLL_CTRL1 0x145
|
||||
#define SYS_9XX_PLL_CTRL2 0x146
|
||||
#define SYS_9XX_PLL_CTRL3 0x147
|
||||
|
||||
#define SYS_9XX_PLL_CTRL0_DEVX(x) (0x148 + (x) * 4)
|
||||
#define SYS_9XX_PLL_CTRL1_DEVX(x) (0x149 + (x) * 4)
|
||||
#define SYS_9XX_PLL_CTRL2_DEVX(x) (0x14a + (x) * 4)
|
||||
#define SYS_9XX_PLL_CTRL3_DEVX(x) (0x14b + (x) * 4)
|
||||
|
||||
#define SYS_9XX_CPU_PLL_CHG_CTRL 0x188
|
||||
#define SYS_9XX_PLL_CHG_CTRL 0x189
|
||||
#define SYS_9XX_CLK_DEV_DIS 0x18a
|
||||
#define SYS_9XX_CLK_DEV_SEL 0x18b
|
||||
#define SYS_9XX_CLK_DEV_DIV 0x18d
|
||||
#define SYS_9XX_CLK_DEV_CHG 0x18f
|
||||
|
||||
/* Registers changed on 9XX */
|
||||
#define SYS_9XX_POWER_ON_RESET_CFG 0x00
|
||||
#define SYS_9XX_CHIP_RESET 0x01
|
||||
@@ -170,6 +200,11 @@
|
||||
#define nlm_get_fuse_regbase(node) \
|
||||
(nlm_get_fuse_pcibase(node) + XLP_IO_PCI_HDRSZ)
|
||||
|
||||
#define nlm_get_clock_pcibase(node) \
|
||||
nlm_pcicfg_base(XLP9XX_IO_CLOCK_OFFSET(node))
|
||||
#define nlm_get_clock_regbase(node) \
|
||||
(nlm_get_clock_pcibase(node) + XLP_IO_PCI_HDRSZ)
|
||||
|
||||
unsigned int nlm_get_pic_frequency(int node);
|
||||
#endif
|
||||
#endif
|
||||
|
@@ -58,6 +58,10 @@
|
||||
#define PIC_I2C_1_IRQ 31
|
||||
#define PIC_I2C_2_IRQ 32
|
||||
#define PIC_I2C_3_IRQ 33
|
||||
#define PIC_SPI_IRQ 34
|
||||
#define PIC_NAND_IRQ 37
|
||||
#define PIC_SATA_IRQ 38
|
||||
#define PIC_GPIO_IRQ 39
|
||||
|
||||
#define PIC_PCIE_LINK_MSI_IRQ_BASE 44 /* 44 - 47 MSI IRQ */
|
||||
#define PIC_PCIE_LINK_MSI_IRQ(i) (44 + (i))
|
||||
@@ -66,8 +70,9 @@
|
||||
#define PIC_PCIE_MSIX_IRQ_BASE 48 /* 48 - 51 MSI-X IRQ */
|
||||
#define PIC_PCIE_MSIX_IRQ(i) (48 + (i))
|
||||
|
||||
#define NLM_MSIX_VEC_BASE 96 /* 96 - 127 - MSIX mapped */
|
||||
#define NLM_MSI_VEC_BASE 128 /* 128 -255 - MSI mapped */
|
||||
/* XLP9xx and XLP8xx has 128 and 32 MSIX vectors respectively */
|
||||
#define NLM_MSIX_VEC_BASE 96 /* 96 - 223 - MSIX mapped */
|
||||
#define NLM_MSI_VEC_BASE 224 /* 224 -351 - MSI mapped */
|
||||
|
||||
#define NLM_PIC_INDIRECT_VEC_BASE 512
|
||||
#define NLM_GPIO_VEC_BASE 768
|
||||
@@ -95,17 +100,19 @@ void *xlp_dt_init(void *fdtp);
|
||||
|
||||
static inline int cpu_is_xlpii(void)
|
||||
{
|
||||
int chip = read_c0_prid() & 0xff00;
|
||||
int chip = read_c0_prid() & PRID_IMP_MASK;
|
||||
|
||||
return chip == PRID_IMP_NETLOGIC_XLP2XX ||
|
||||
chip == PRID_IMP_NETLOGIC_XLP9XX;
|
||||
chip == PRID_IMP_NETLOGIC_XLP9XX ||
|
||||
chip == PRID_IMP_NETLOGIC_XLP5XX;
|
||||
}
|
||||
|
||||
static inline int cpu_is_xlp9xx(void)
|
||||
{
|
||||
int chip = read_c0_prid() & 0xff00;
|
||||
int chip = read_c0_prid() & PRID_IMP_MASK;
|
||||
|
||||
return chip == PRID_IMP_NETLOGIC_XLP9XX;
|
||||
return chip == PRID_IMP_NETLOGIC_XLP9XX ||
|
||||
chip == PRID_IMP_NETLOGIC_XLP5XX;
|
||||
}
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
#endif /* _ASM_NLM_XLP_H */
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* asm-mips/nile4.h -- NEC Vrc-5074 Nile 4 definitions
|
||||
*
|
||||
* Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
|
||||
* Copyright (C) 2000 Geert Uytterhoeven <geert@linux-m68k.org>
|
||||
* Sony Software Development Center Europe (SDCE), Brussels
|
||||
*
|
||||
* This file is based on the following documentation:
|
||||
|
@@ -211,7 +211,6 @@ union octeon_cvmemctl {
|
||||
|
||||
extern void octeon_write_lcd(const char *s);
|
||||
extern void octeon_check_cpu_bist(void);
|
||||
extern int octeon_get_boot_debug_flag(void);
|
||||
extern int octeon_get_boot_uart(void);
|
||||
|
||||
struct uart_port;
|
||||
|
@@ -32,6 +32,8 @@ struct vm_area_struct;
|
||||
_page_cachable_default)
|
||||
#define PAGE_KERNEL __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
|
||||
_PAGE_GLOBAL | _page_cachable_default)
|
||||
#define PAGE_KERNEL_NC __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
|
||||
_PAGE_GLOBAL | _CACHE_CACHABLE_NONCOHERENT)
|
||||
#define PAGE_USERIO __pgprot(_PAGE_PRESENT | (cpu_has_rixi ? 0 : _PAGE_READ) | _PAGE_WRITE | \
|
||||
_page_cachable_default)
|
||||
#define PAGE_KERNEL_UNCACHED __pgprot(_PAGE_PRESENT | __READABLE | \
|
||||
|
51
arch/mips/include/asm/pm-cps.h
Normal file
51
arch/mips/include/asm/pm-cps.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Imagination Technologies
|
||||
* Author: Paul Burton <paul.burton@imgtec.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef __MIPS_ASM_PM_CPS_H__
|
||||
#define __MIPS_ASM_PM_CPS_H__
|
||||
|
||||
/*
|
||||
* The CM & CPC can only handle coherence & power control on a per-core basis,
|
||||
* thus in an MT system the VPEs within each core are coupled and can only
|
||||
* enter or exit states requiring CM or CPC assistance in unison.
|
||||
*/
|
||||
#ifdef CONFIG_MIPS_MT
|
||||
# define coupled_coherence cpu_has_mipsmt
|
||||
#else
|
||||
# define coupled_coherence 0
|
||||
#endif
|
||||
|
||||
/* Enumeration of possible PM states */
|
||||
enum cps_pm_state {
|
||||
CPS_PM_NC_WAIT, /* MIPS wait instruction, non-coherent */
|
||||
CPS_PM_CLOCK_GATED, /* Core clock gated */
|
||||
CPS_PM_POWER_GATED, /* Core power gated */
|
||||
CPS_PM_STATE_COUNT,
|
||||
};
|
||||
|
||||
/**
|
||||
* cps_pm_support_state - determine whether the system supports a PM state
|
||||
* @state: the state to test for support
|
||||
*
|
||||
* Returns true if the system supports the given state, otherwise false.
|
||||
*/
|
||||
extern bool cps_pm_support_state(enum cps_pm_state state);
|
||||
|
||||
/**
|
||||
* cps_pm_enter_state - enter a PM state
|
||||
* @state: the state to enter
|
||||
*
|
||||
* Enter the given PM state. If coupled_coherence is non-zero then it is
|
||||
* expected that this function be called at approximately the same time on
|
||||
* each coupled CPU. Returns 0 on successful entry & exit, otherwise -errno.
|
||||
*/
|
||||
extern int cps_pm_enter_state(enum cps_pm_state state);
|
||||
|
||||
#endif /* __MIPS_ASM_PM_CPS_H__ */
|
159
arch/mips/include/asm/pm.h
Normal file
159
arch/mips/include/asm/pm.h
Normal file
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Imagination Technologies Ltd
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* PM helper macros for CPU power off (e.g. Suspend-to-RAM).
|
||||
*/
|
||||
|
||||
#ifndef __ASM_PM_H
|
||||
#define __ASM_PM_H
|
||||
|
||||
#ifdef __ASSEMBLY__
|
||||
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/asm.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/regdef.h>
|
||||
|
||||
/* Save CPU state to stack for suspend to RAM */
|
||||
.macro SUSPEND_SAVE_REGS
|
||||
subu sp, PT_SIZE
|
||||
/* Call preserved GPRs */
|
||||
LONG_S $16, PT_R16(sp)
|
||||
LONG_S $17, PT_R17(sp)
|
||||
LONG_S $18, PT_R18(sp)
|
||||
LONG_S $19, PT_R19(sp)
|
||||
LONG_S $20, PT_R20(sp)
|
||||
LONG_S $21, PT_R21(sp)
|
||||
LONG_S $22, PT_R22(sp)
|
||||
LONG_S $23, PT_R23(sp)
|
||||
LONG_S $28, PT_R28(sp)
|
||||
LONG_S $30, PT_R30(sp)
|
||||
LONG_S $31, PT_R31(sp)
|
||||
/* A couple of CP0 registers with space in pt_regs */
|
||||
mfc0 k0, CP0_STATUS
|
||||
LONG_S k0, PT_STATUS(sp)
|
||||
.endm
|
||||
|
||||
/* Restore CPU state from stack after resume from RAM */
|
||||
.macro RESUME_RESTORE_REGS_RETURN
|
||||
.set push
|
||||
.set noreorder
|
||||
/* A couple of CP0 registers with space in pt_regs */
|
||||
LONG_L k0, PT_STATUS(sp)
|
||||
mtc0 k0, CP0_STATUS
|
||||
/* Call preserved GPRs */
|
||||
LONG_L $16, PT_R16(sp)
|
||||
LONG_L $17, PT_R17(sp)
|
||||
LONG_L $18, PT_R18(sp)
|
||||
LONG_L $19, PT_R19(sp)
|
||||
LONG_L $20, PT_R20(sp)
|
||||
LONG_L $21, PT_R21(sp)
|
||||
LONG_L $22, PT_R22(sp)
|
||||
LONG_L $23, PT_R23(sp)
|
||||
LONG_L $28, PT_R28(sp)
|
||||
LONG_L $30, PT_R30(sp)
|
||||
LONG_L $31, PT_R31(sp)
|
||||
/* Pop and return */
|
||||
jr ra
|
||||
addiu sp, PT_SIZE
|
||||
.set pop
|
||||
.endm
|
||||
|
||||
/* Get address of static suspend state into t1 */
|
||||
.macro LA_STATIC_SUSPEND
|
||||
la t1, mips_static_suspend_state
|
||||
.endm
|
||||
|
||||
/* Save important CPU state for early restoration to global data */
|
||||
.macro SUSPEND_SAVE_STATIC
|
||||
#ifdef CONFIG_EVA
|
||||
/*
|
||||
* Segment configuration is saved in global data where it can be easily
|
||||
* reloaded without depending on the segment configuration.
|
||||
*/
|
||||
mfc0 k0, CP0_PAGEMASK, 2 /* SegCtl0 */
|
||||
LONG_S k0, SSS_SEGCTL0(t1)
|
||||
mfc0 k0, CP0_PAGEMASK, 3 /* SegCtl1 */
|
||||
LONG_S k0, SSS_SEGCTL1(t1)
|
||||
mfc0 k0, CP0_PAGEMASK, 4 /* SegCtl2 */
|
||||
LONG_S k0, SSS_SEGCTL2(t1)
|
||||
#endif
|
||||
/* save stack pointer (pointing to GPRs) */
|
||||
LONG_S sp, SSS_SP(t1)
|
||||
.endm
|
||||
|
||||
/* Restore important CPU state early from global data */
|
||||
.macro RESUME_RESTORE_STATIC
|
||||
#ifdef CONFIG_EVA
|
||||
/*
|
||||
* Segment configuration must be restored prior to any access to
|
||||
* allocated memory, as it may reside outside of the legacy kernel
|
||||
* segments.
|
||||
*/
|
||||
LONG_L k0, SSS_SEGCTL0(t1)
|
||||
mtc0 k0, CP0_PAGEMASK, 2 /* SegCtl0 */
|
||||
LONG_L k0, SSS_SEGCTL1(t1)
|
||||
mtc0 k0, CP0_PAGEMASK, 3 /* SegCtl1 */
|
||||
LONG_L k0, SSS_SEGCTL2(t1)
|
||||
mtc0 k0, CP0_PAGEMASK, 4 /* SegCtl2 */
|
||||
tlbw_use_hazard
|
||||
#endif
|
||||
/* restore stack pointer (pointing to GPRs) */
|
||||
LONG_L sp, SSS_SP(t1)
|
||||
.endm
|
||||
|
||||
/* flush caches to make sure context has reached memory */
|
||||
.macro SUSPEND_CACHE_FLUSH
|
||||
.extern __wback_cache_all
|
||||
.set push
|
||||
.set noreorder
|
||||
la t1, __wback_cache_all
|
||||
LONG_L t0, 0(t1)
|
||||
jalr t0
|
||||
nop
|
||||
.set pop
|
||||
.endm
|
||||
|
||||
/* Save suspend state and flush data caches to RAM */
|
||||
.macro SUSPEND_SAVE
|
||||
SUSPEND_SAVE_REGS
|
||||
LA_STATIC_SUSPEND
|
||||
SUSPEND_SAVE_STATIC
|
||||
SUSPEND_CACHE_FLUSH
|
||||
.endm
|
||||
|
||||
/* Restore saved state after resume from RAM and return */
|
||||
.macro RESUME_RESTORE_RETURN
|
||||
LA_STATIC_SUSPEND
|
||||
RESUME_RESTORE_STATIC
|
||||
RESUME_RESTORE_REGS_RETURN
|
||||
.endm
|
||||
|
||||
#else /* __ASSEMBLY__ */
|
||||
|
||||
/**
|
||||
* struct mips_static_suspend_state - Core saved CPU state across S2R.
|
||||
* @segctl: CP0 Segment control registers.
|
||||
* @sp: Stack frame where GP register context is saved.
|
||||
*
|
||||
* This structure contains minimal CPU state that must be saved in static kernel
|
||||
* data in order to be able to restore the rest of the state. This includes
|
||||
* segmentation configuration in the case of EVA being enabled, as they must be
|
||||
* restored prior to any kmalloc'd memory being referenced (even the stack
|
||||
* pointer).
|
||||
*/
|
||||
struct mips_static_suspend_state {
|
||||
#ifdef CONFIG_EVA
|
||||
unsigned long segctl[3];
|
||||
#endif
|
||||
unsigned long sp;
|
||||
};
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#endif /* __ASM_PM_HELPERS_H */
|
@@ -39,9 +39,6 @@ struct pt_regs {
|
||||
unsigned long cp0_badvaddr;
|
||||
unsigned long cp0_cause;
|
||||
unsigned long cp0_epc;
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
unsigned long cp0_tcstatus;
|
||||
#endif /* CONFIG_MIPS_MT_SMTC */
|
||||
#ifdef CONFIG_CPU_CAVIUM_OCTEON
|
||||
unsigned long long mpl[3]; /* MTM{0,1,2} */
|
||||
unsigned long long mtp[3]; /* MTP{0,1,2} */
|
||||
|
@@ -43,11 +43,10 @@
|
||||
: "i" (op), "R" (*(unsigned char *)(addr)))
|
||||
|
||||
#ifdef CONFIG_MIPS_MT
|
||||
/*
|
||||
* Temporary hacks for SMTC debug. Optionally force single-threaded
|
||||
* execution during I-cache flushes.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Optionally force single-threaded execution during I-cache flushes.
|
||||
*/
|
||||
#define PROTECT_CACHE_FLUSHES 1
|
||||
|
||||
#ifdef PROTECT_CACHE_FLUSHES
|
||||
@@ -524,6 +523,8 @@ __BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 32,
|
||||
__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 64, )
|
||||
__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 64, )
|
||||
__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 64, )
|
||||
__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 128, )
|
||||
__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 128, )
|
||||
__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 128, )
|
||||
|
||||
__BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 16, )
|
||||
|
@@ -69,6 +69,8 @@
|
||||
#define SGI_EISA_IRQ SGINT_LOCAL2 + 3 /* EISA interrupts */
|
||||
#define SGI_KEYBD_IRQ SGINT_LOCAL2 + 4 /* keyboard */
|
||||
#define SGI_SERIAL_IRQ SGINT_LOCAL2 + 5 /* onboard serial */
|
||||
#define SGI_GIOEXP0_IRQ (SGINT_LOCAL2 + 6) /* Indy GIO EXP0 */
|
||||
#define SGI_GIOEXP1_IRQ (SGINT_LOCAL2 + 7) /* Indy GIO EXP1 */
|
||||
|
||||
#define ip22_is_fullhouse() (sgioc->sysid & SGIOC_SYSID_FULLHOUSE)
|
||||
|
||||
|
@@ -13,17 +13,28 @@
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
struct boot_config {
|
||||
unsigned int core;
|
||||
unsigned int vpe;
|
||||
struct vpe_boot_config {
|
||||
unsigned long pc;
|
||||
unsigned long sp;
|
||||
unsigned long gp;
|
||||
};
|
||||
|
||||
extern struct boot_config mips_cps_bootcfg;
|
||||
struct core_boot_config {
|
||||
atomic_t vpe_mask;
|
||||
struct vpe_boot_config *vpe_config;
|
||||
};
|
||||
|
||||
extern struct core_boot_config *mips_cps_core_bootcfg;
|
||||
|
||||
extern void mips_cps_core_entry(void);
|
||||
extern void mips_cps_core_init(void);
|
||||
|
||||
extern struct vpe_boot_config *mips_cps_boot_vpes(void);
|
||||
|
||||
extern bool mips_cps_smp_in_use(void);
|
||||
|
||||
extern void mips_cps_pm_save(void);
|
||||
extern void mips_cps_pm_restore(void);
|
||||
|
||||
#else /* __ASSEMBLY__ */
|
||||
|
||||
|
@@ -26,7 +26,6 @@ struct plat_smp_ops {
|
||||
void (*send_ipi_mask)(const struct cpumask *mask, unsigned int action);
|
||||
void (*init_secondary)(void);
|
||||
void (*smp_finish)(void);
|
||||
void (*cpus_done)(void);
|
||||
void (*boot_secondary)(int cpu, struct task_struct *idle);
|
||||
void (*smp_setup)(void);
|
||||
void (*prepare_cpus)(unsigned int max_cpus);
|
||||
|
@@ -46,6 +46,9 @@ extern int __cpu_logical_map[NR_CPUS];
|
||||
|
||||
extern volatile cpumask_t cpu_callin_map;
|
||||
|
||||
/* Mask of CPUs which are currently definitely operating coherently */
|
||||
extern cpumask_t cpu_coherent_mask;
|
||||
|
||||
extern void asmlinkage smp_bootstrap(void);
|
||||
|
||||
/*
|
||||
|
@@ -1,78 +0,0 @@
|
||||
#ifndef _ASM_SMTC_MT_H
|
||||
#define _ASM_SMTC_MT_H
|
||||
|
||||
/*
|
||||
* Definitions for SMTC multitasking on MIPS MT cores
|
||||
*/
|
||||
|
||||
#include <asm/mips_mt.h>
|
||||
#include <asm/smtc_ipi.h>
|
||||
|
||||
/*
|
||||
* System-wide SMTC status information
|
||||
*/
|
||||
|
||||
extern unsigned int smtc_status;
|
||||
|
||||
#define SMTC_TLB_SHARED 0x00000001
|
||||
#define SMTC_MTC_ACTIVE 0x00000002
|
||||
|
||||
/*
|
||||
* TLB/ASID Management information
|
||||
*/
|
||||
|
||||
#define MAX_SMTC_TLBS 2
|
||||
#define MAX_SMTC_ASIDS 256
|
||||
#if NR_CPUS <= 8
|
||||
typedef char asiduse;
|
||||
#else
|
||||
#if NR_CPUS <= 16
|
||||
typedef short asiduse;
|
||||
#else
|
||||
typedef long asiduse;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* VPE Management information
|
||||
*/
|
||||
|
||||
#define MAX_SMTC_VPES MAX_SMTC_TLBS /* FIXME: May not always be true. */
|
||||
|
||||
extern asiduse smtc_live_asid[MAX_SMTC_TLBS][MAX_SMTC_ASIDS];
|
||||
|
||||
struct mm_struct;
|
||||
struct task_struct;
|
||||
|
||||
void smtc_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu);
|
||||
void self_ipi(struct smtc_ipi *);
|
||||
void smtc_flush_tlb_asid(unsigned long asid);
|
||||
extern int smtc_build_cpu_map(int startslot);
|
||||
extern void smtc_prepare_cpus(int cpus);
|
||||
extern void smtc_smp_finish(void);
|
||||
extern void smtc_boot_secondary(int cpu, struct task_struct *t);
|
||||
extern void smtc_cpus_done(void);
|
||||
extern void smtc_init_secondary(void);
|
||||
|
||||
|
||||
/*
|
||||
* Sharing the TLB between multiple VPEs means that the
|
||||
* "random" index selection function is not allowed to
|
||||
* select the current value of the Index register. To
|
||||
* avoid additional TLB pressure, the Index registers
|
||||
* are "parked" with an non-Valid value.
|
||||
*/
|
||||
|
||||
#define PARKED_INDEX ((unsigned int)0x80000000)
|
||||
|
||||
/*
|
||||
* Define low-level interrupt mask for IPIs, if necessary.
|
||||
* By default, use SW interrupt 1, which requires no external
|
||||
* hardware support, but which works only for single-core
|
||||
* MIPS MT systems.
|
||||
*/
|
||||
#ifndef MIPS_CPU_IPI_IRQ
|
||||
#define MIPS_CPU_IPI_IRQ 1
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_SMTC_MT_H */
|
@@ -1,129 +0,0 @@
|
||||
/*
|
||||
* Definitions used in MIPS MT SMTC "Interprocessor Interrupt" code.
|
||||
*/
|
||||
#ifndef __ASM_SMTC_IPI_H
|
||||
#define __ASM_SMTC_IPI_H
|
||||
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
//#define SMTC_IPI_DEBUG
|
||||
|
||||
#ifdef SMTC_IPI_DEBUG
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/mipsmtregs.h>
|
||||
#endif /* SMTC_IPI_DEBUG */
|
||||
|
||||
/*
|
||||
* An IPI "message"
|
||||
*/
|
||||
|
||||
struct smtc_ipi {
|
||||
struct smtc_ipi *flink;
|
||||
int type;
|
||||
void *arg;
|
||||
int dest;
|
||||
#ifdef SMTC_IPI_DEBUG
|
||||
int sender;
|
||||
long stamp;
|
||||
#endif /* SMTC_IPI_DEBUG */
|
||||
};
|
||||
|
||||
/*
|
||||
* Defined IPI Types
|
||||
*/
|
||||
|
||||
#define LINUX_SMP_IPI 1
|
||||
#define SMTC_CLOCK_TICK 2
|
||||
#define IRQ_AFFINITY_IPI 3
|
||||
|
||||
/*
|
||||
* A queue of IPI messages
|
||||
*/
|
||||
|
||||
struct smtc_ipi_q {
|
||||
struct smtc_ipi *head;
|
||||
spinlock_t lock;
|
||||
struct smtc_ipi *tail;
|
||||
int depth;
|
||||
int resched_flag; /* reschedule already queued */
|
||||
};
|
||||
|
||||
static inline void smtc_ipi_nq(struct smtc_ipi_q *q, struct smtc_ipi *p)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&q->lock, flags);
|
||||
if (q->head == NULL)
|
||||
q->head = q->tail = p;
|
||||
else
|
||||
q->tail->flink = p;
|
||||
p->flink = NULL;
|
||||
q->tail = p;
|
||||
q->depth++;
|
||||
#ifdef SMTC_IPI_DEBUG
|
||||
p->sender = read_c0_tcbind();
|
||||
p->stamp = read_c0_count();
|
||||
#endif /* SMTC_IPI_DEBUG */
|
||||
spin_unlock_irqrestore(&q->lock, flags);
|
||||
}
|
||||
|
||||
static inline struct smtc_ipi *__smtc_ipi_dq(struct smtc_ipi_q *q)
|
||||
{
|
||||
struct smtc_ipi *p;
|
||||
|
||||
if (q->head == NULL)
|
||||
p = NULL;
|
||||
else {
|
||||
p = q->head;
|
||||
q->head = q->head->flink;
|
||||
q->depth--;
|
||||
/* Arguably unnecessary, but leaves queue cleaner */
|
||||
if (q->head == NULL)
|
||||
q->tail = NULL;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
static inline struct smtc_ipi *smtc_ipi_dq(struct smtc_ipi_q *q)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct smtc_ipi *p;
|
||||
|
||||
spin_lock_irqsave(&q->lock, flags);
|
||||
p = __smtc_ipi_dq(q);
|
||||
spin_unlock_irqrestore(&q->lock, flags);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
static inline void smtc_ipi_req(struct smtc_ipi_q *q, struct smtc_ipi *p)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&q->lock, flags);
|
||||
if (q->head == NULL) {
|
||||
q->head = q->tail = p;
|
||||
p->flink = NULL;
|
||||
} else {
|
||||
p->flink = q->head;
|
||||
q->head = p;
|
||||
}
|
||||
q->depth++;
|
||||
spin_unlock_irqrestore(&q->lock, flags);
|
||||
}
|
||||
|
||||
static inline int smtc_ipi_qdepth(struct smtc_ipi_q *q)
|
||||
{
|
||||
unsigned long flags;
|
||||
int retval;
|
||||
|
||||
spin_lock_irqsave(&q->lock, flags);
|
||||
retval = q->depth;
|
||||
spin_unlock_irqrestore(&q->lock, flags);
|
||||
return retval;
|
||||
}
|
||||
|
||||
extern void smtc_send_ipi(int cpu, int type, unsigned int action);
|
||||
|
||||
#endif /* __ASM_SMTC_IPI_H */
|
@@ -1,23 +0,0 @@
|
||||
/*
|
||||
* Definitions for SMTC /proc entries
|
||||
* Copyright(C) 2005 MIPS Technologies Inc.
|
||||
*/
|
||||
#ifndef __ASM_SMTC_PROC_H
|
||||
#define __ASM_SMTC_PROC_H
|
||||
|
||||
/*
|
||||
* per-"CPU" statistics
|
||||
*/
|
||||
|
||||
struct smtc_cpu_proc {
|
||||
unsigned long timerints;
|
||||
unsigned long selfipis;
|
||||
};
|
||||
|
||||
extern struct smtc_cpu_proc smtc_cpu_stats[NR_CPUS];
|
||||
|
||||
/* Count of number of recoveries of "stolen" FPU access rights on 34K */
|
||||
|
||||
extern atomic_t smtc_fpu_recoveries;
|
||||
|
||||
#endif /* __ASM_SMTC_PROC_H */
|
@@ -19,22 +19,12 @@
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/thread_info.h>
|
||||
|
||||
/*
|
||||
* For SMTC kernel, global IE should be left set, and interrupts
|
||||
* controlled exclusively via IXMT.
|
||||
*/
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
#define STATMASK 0x1e
|
||||
#elif defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
|
||||
#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
|
||||
#define STATMASK 0x3f
|
||||
#else
|
||||
#define STATMASK 0x1f
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
#include <asm/mipsmtregs.h>
|
||||
#endif /* CONFIG_MIPS_MT_SMTC */
|
||||
|
||||
.macro SAVE_AT
|
||||
.set push
|
||||
.set noat
|
||||
@@ -186,16 +176,6 @@
|
||||
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
|
||||
* to cover the pipeline delay.
|
||||
*/
|
||||
.set mips32
|
||||
mfc0 k0, CP0_TCSTATUS
|
||||
.set mips0
|
||||
LONG_S k0, PT_TCSTATUS(sp)
|
||||
#endif /* CONFIG_MIPS_MT_SMTC */
|
||||
LONG_S $4, PT_R4(sp)
|
||||
mfc0 v1, CP0_CAUSE
|
||||
LONG_S $5, PT_R5(sp)
|
||||
@@ -321,36 +301,6 @@
|
||||
.set push
|
||||
.set reorder
|
||||
.set noat
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
.set mips32r2
|
||||
/*
|
||||
* We need to make sure the read-modify-write
|
||||
* of Status below isn't perturbed by an interrupt
|
||||
* or cross-TC access, so we need to do at least a DMT,
|
||||
* protected by an interrupt-inhibit. But setting IXMT
|
||||
* also creates a few-cycle window where an IPI could
|
||||
* be queued and not be detected before potentially
|
||||
* returning to a WAIT or user-mode loop. It must be
|
||||
* replayed.
|
||||
*
|
||||
* We're in the middle of a context switch, and
|
||||
* we can't dispatch it directly without trashing
|
||||
* some registers, so we'll try to detect this unlikely
|
||||
* case and program a software interrupt in the VPE,
|
||||
* as would be done for a cross-VPE IPI. To accommodate
|
||||
* the handling of that case, we're doing a DVPE instead
|
||||
* of just a DMT here to protect against other threads.
|
||||
* This is a lot of cruft to cover a tiny window.
|
||||
* If you can find a better design, implement it!
|
||||
*
|
||||
*/
|
||||
mfc0 v0, CP0_TCSTATUS
|
||||
ori v0, TCSTATUS_IXMT
|
||||
mtc0 v0, CP0_TCSTATUS
|
||||
_ehb
|
||||
DVPE 5 # dvpe a1
|
||||
jal mips_ihb
|
||||
#endif /* CONFIG_MIPS_MT_SMTC */
|
||||
mfc0 a0, CP0_STATUS
|
||||
ori a0, STATMASK
|
||||
xori a0, STATMASK
|
||||
@@ -362,59 +312,6 @@
|
||||
and v0, v1
|
||||
or v0, a0
|
||||
mtc0 v0, CP0_STATUS
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
/*
|
||||
* Only after EXL/ERL have been restored to status can we
|
||||
* restore TCStatus.IXMT.
|
||||
*/
|
||||
LONG_L v1, PT_TCSTATUS(sp)
|
||||
_ehb
|
||||
mfc0 a0, CP0_TCSTATUS
|
||||
andi v1, TCSTATUS_IXMT
|
||||
bnez v1, 0f
|
||||
|
||||
/*
|
||||
* We'd like to detect any IPIs queued in the tiny window
|
||||
* above and request an software interrupt to service them
|
||||
* when we ERET.
|
||||
*
|
||||
* Computing the offset into the IPIQ array of the executing
|
||||
* TC's IPI queue in-line would be tedious. We use part of
|
||||
* the TCContext register to hold 16 bits of offset that we
|
||||
* can add in-line to find the queue head.
|
||||
*/
|
||||
mfc0 v0, CP0_TCCONTEXT
|
||||
la a2, IPIQ
|
||||
srl v0, v0, 16
|
||||
addu a2, a2, v0
|
||||
LONG_L v0, 0(a2)
|
||||
beqz v0, 0f
|
||||
/*
|
||||
* If we have a queue, provoke dispatch within the VPE by setting C_SW1
|
||||
*/
|
||||
mfc0 v0, CP0_CAUSE
|
||||
ori v0, v0, C_SW1
|
||||
mtc0 v0, CP0_CAUSE
|
||||
0:
|
||||
/*
|
||||
* This test should really never branch but
|
||||
* let's be prudent here. Having atomized
|
||||
* the shared register modifications, we can
|
||||
* now EVPE, and must do so before interrupts
|
||||
* are potentially re-enabled.
|
||||
*/
|
||||
andi a1, a1, MVPCONTROL_EVP
|
||||
beqz a1, 1f
|
||||
evpe
|
||||
1:
|
||||
/* We know that TCStatua.IXMT should be set from above */
|
||||
xori a0, a0, TCSTATUS_IXMT
|
||||
or a0, a0, v1
|
||||
mtc0 a0, CP0_TCSTATUS
|
||||
_ehb
|
||||
|
||||
.set mips0
|
||||
#endif /* CONFIG_MIPS_MT_SMTC */
|
||||
LONG_L v1, PT_EPC(sp)
|
||||
MTC0 v1, CP0_EPC
|
||||
LONG_L $31, PT_R31(sp)
|
||||
@@ -467,33 +364,11 @@
|
||||
* Set cp0 enable bit as sign that we're running on the kernel stack
|
||||
*/
|
||||
.macro CLI
|
||||
#if !defined(CONFIG_MIPS_MT_SMTC)
|
||||
mfc0 t0, CP0_STATUS
|
||||
li t1, ST0_CU0 | STATMASK
|
||||
or t0, t1
|
||||
xori t0, STATMASK
|
||||
mtc0 t0, CP0_STATUS
|
||||
#else /* CONFIG_MIPS_MT_SMTC */
|
||||
/*
|
||||
* For SMTC, we need to set privilege
|
||||
* and disable interrupts only for the
|
||||
* current TC, using the TCStatus register.
|
||||
*/
|
||||
mfc0 t0, CP0_TCSTATUS
|
||||
/* Fortunately CU 0 is in the same place in both registers */
|
||||
/* Set TCU0, TMX, TKSU (for later inversion) and IXMT */
|
||||
li t1, ST0_CU0 | 0x08001c00
|
||||
or t0, t1
|
||||
/* Clear TKSU, leave IXMT */
|
||||
xori t0, 0x00001800
|
||||
mtc0 t0, CP0_TCSTATUS
|
||||
_ehb
|
||||
/* We need to leave the global IE bit set, but clear EXL...*/
|
||||
mfc0 t0, CP0_STATUS
|
||||
ori t0, ST0_EXL | ST0_ERL
|
||||
xori t0, ST0_EXL | ST0_ERL
|
||||
mtc0 t0, CP0_STATUS
|
||||
#endif /* CONFIG_MIPS_MT_SMTC */
|
||||
irq_disable_hazard
|
||||
.endm
|
||||
|
||||
@@ -502,35 +377,11 @@
|
||||
* Set cp0 enable bit as sign that we're running on the kernel stack
|
||||
*/
|
||||
.macro STI
|
||||
#if !defined(CONFIG_MIPS_MT_SMTC)
|
||||
mfc0 t0, CP0_STATUS
|
||||
li t1, ST0_CU0 | STATMASK
|
||||
or t0, t1
|
||||
xori t0, STATMASK & ~1
|
||||
mtc0 t0, CP0_STATUS
|
||||
#else /* CONFIG_MIPS_MT_SMTC */
|
||||
/*
|
||||
* For SMTC, we need to set privilege
|
||||
* and enable interrupts only for the
|
||||
* current TC, using the TCStatus register.
|
||||
*/
|
||||
_ehb
|
||||
mfc0 t0, CP0_TCSTATUS
|
||||
/* Fortunately CU 0 is in the same place in both registers */
|
||||
/* Set TCU0, TKSU (for later inversion) and IXMT */
|
||||
li t1, ST0_CU0 | 0x08001c00
|
||||
or t0, t1
|
||||
/* Clear TKSU *and* IXMT */
|
||||
xori t0, 0x00001c00
|
||||
mtc0 t0, CP0_TCSTATUS
|
||||
_ehb
|
||||
/* We need to leave the global IE bit set, but clear EXL...*/
|
||||
mfc0 t0, CP0_STATUS
|
||||
ori t0, ST0_EXL
|
||||
xori t0, ST0_EXL
|
||||
mtc0 t0, CP0_STATUS
|
||||
/* irq_enable_hazard below should expand to EHB for 24K/34K cpus */
|
||||
#endif /* CONFIG_MIPS_MT_SMTC */
|
||||
irq_enable_hazard
|
||||
.endm
|
||||
|
||||
@@ -540,32 +391,6 @@
|
||||
* Set cp0 enable bit as sign that we're running on the kernel stack
|
||||
*/
|
||||
.macro KMODE
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
/*
|
||||
* This gets baroque in SMTC. We want to
|
||||
* protect the non-atomic clearing of EXL
|
||||
* with DMT/EMT, but we don't want to take
|
||||
* an interrupt while DMT is still in effect.
|
||||
*/
|
||||
|
||||
/* KMODE gets invoked from both reorder and noreorder code */
|
||||
.set push
|
||||
.set mips32r2
|
||||
.set noreorder
|
||||
mfc0 v0, CP0_TCSTATUS
|
||||
andi v1, v0, TCSTATUS_IXMT
|
||||
ori v0, TCSTATUS_IXMT
|
||||
mtc0 v0, CP0_TCSTATUS
|
||||
_ehb
|
||||
DMT 2 # dmt v0
|
||||
/*
|
||||
* We don't know a priori if ra is "live"
|
||||
*/
|
||||
move t0, ra
|
||||
jal mips_ihb
|
||||
nop /* delay slot */
|
||||
move ra, t0
|
||||
#endif /* CONFIG_MIPS_MT_SMTC */
|
||||
mfc0 t0, CP0_STATUS
|
||||
li t1, ST0_CU0 | (STATMASK & ~1)
|
||||
#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
|
||||
@@ -576,25 +401,6 @@
|
||||
or t0, t1
|
||||
xori t0, STATMASK & ~1
|
||||
mtc0 t0, CP0_STATUS
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
_ehb
|
||||
andi v0, v0, VPECONTROL_TE
|
||||
beqz v0, 2f
|
||||
nop /* delay slot */
|
||||
emt
|
||||
2:
|
||||
mfc0 v0, CP0_TCSTATUS
|
||||
/* Clear IXMT, then OR in previous value */
|
||||
ori v0, TCSTATUS_IXMT
|
||||
xori v0, TCSTATUS_IXMT
|
||||
or v0, v1, v0
|
||||
mtc0 v0, CP0_TCSTATUS
|
||||
/*
|
||||
* irq_disable_hazard below should expand to EHB
|
||||
* on 24K/34K CPUS
|
||||
*/
|
||||
.set pop
|
||||
#endif /* CONFIG_MIPS_MT_SMTC */
|
||||
irq_disable_hazard
|
||||
.endm
|
||||
|
||||
|
@@ -159,11 +159,7 @@ static inline struct thread_info *current_thread_info(void)
|
||||
* We stash processor id into a COP0 register to retrieve it fast
|
||||
* at kernel exception entry.
|
||||
*/
|
||||
#if defined(CONFIG_MIPS_MT_SMTC)
|
||||
#define SMP_CPUID_REG 2, 2 /* TCBIND */
|
||||
#define ASM_SMP_CPUID_REG $2, 2
|
||||
#define SMP_CPUID_PTRSHIFT 19
|
||||
#elif defined(CONFIG_MIPS_PGD_C0_CONTEXT)
|
||||
#if defined(CONFIG_MIPS_PGD_C0_CONTEXT)
|
||||
#define SMP_CPUID_REG 20, 0 /* XCONTEXT */
|
||||
#define ASM_SMP_CPUID_REG $20
|
||||
#define SMP_CPUID_PTRSHIFT 48
|
||||
@@ -179,13 +175,8 @@ static inline struct thread_info *current_thread_info(void)
|
||||
#define SMP_CPUID_REGSHIFT (SMP_CPUID_PTRSHIFT + 2)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MIPS_MT_SMTC
|
||||
#define ASM_CPUID_MFC0 mfc0
|
||||
#define UASM_i_CPUID_MFC0 uasm_i_mfc0
|
||||
#else
|
||||
#define ASM_CPUID_MFC0 MFC0
|
||||
#define UASM_i_CPUID_MFC0 UASM_i_MFC0
|
||||
#endif
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* _ASM_THREAD_INFO_H */
|
||||
|
@@ -52,14 +52,11 @@ 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
|
||||
return smtc_clockevent_init();
|
||||
#elif defined(CONFIG_CEVT_GIC)
|
||||
#if defined(CONFIG_CEVT_GIC)
|
||||
return (gic_clockevent_init() | r4k_clockevent_init());
|
||||
#elif defined(CONFIG_CEVT_R4K)
|
||||
return r4k_clockevent_init();
|
||||
|
@@ -4,12 +4,16 @@
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (C) 1998, 1999, 2003 by Ralf Baechle
|
||||
* Copyright (C) 2014 by Maciej W. Rozycki
|
||||
*/
|
||||
#ifndef _ASM_TIMEX_H
|
||||
#define _ASM_TIMEX_H
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <linux/compiler.h>
|
||||
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/cpu-features.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/cpu-type.h>
|
||||
@@ -45,30 +49,55 @@ typedef unsigned int cycles_t;
|
||||
* However for now the implementaton of this function doesn't get these
|
||||
* fine details right.
|
||||
*/
|
||||
static inline int can_use_mips_counter(unsigned int prid)
|
||||
{
|
||||
int comp = (prid & PRID_COMP_MASK) != PRID_COMP_LEGACY;
|
||||
|
||||
if (__builtin_constant_p(cpu_has_counter) && !cpu_has_counter)
|
||||
return 0;
|
||||
else if (__builtin_constant_p(cpu_has_mips_r) && cpu_has_mips_r)
|
||||
return 1;
|
||||
else if (likely(!__builtin_constant_p(cpu_has_mips_r) && comp))
|
||||
return 1;
|
||||
/* Make sure we don't peek at cpu_data[0].options in the fast path! */
|
||||
if (!__builtin_constant_p(cpu_has_counter))
|
||||
asm volatile("" : "=m" (cpu_data[0].options));
|
||||
if (likely(cpu_has_counter &&
|
||||
prid >= (PRID_IMP_R4000 | PRID_REV_ENCODE_44(5, 0))))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline cycles_t get_cycles(void)
|
||||
{
|
||||
switch (boot_cpu_type()) {
|
||||
case CPU_R4400PC:
|
||||
case CPU_R4400SC:
|
||||
case CPU_R4400MC:
|
||||
if ((read_c0_prid() & 0xff) >= 0x0050)
|
||||
return read_c0_count();
|
||||
break;
|
||||
|
||||
case CPU_R4000PC:
|
||||
case CPU_R4000SC:
|
||||
case CPU_R4000MC:
|
||||
break;
|
||||
|
||||
default:
|
||||
if (cpu_has_counter)
|
||||
return read_c0_count();
|
||||
break;
|
||||
}
|
||||
|
||||
return 0; /* no usable counter */
|
||||
if (can_use_mips_counter(read_c0_prid()))
|
||||
return read_c0_count();
|
||||
else
|
||||
return 0; /* no usable counter */
|
||||
}
|
||||
|
||||
/*
|
||||
* Like get_cycles - but where c0_count is not available we desperately
|
||||
* use c0_random in an attempt to get at least a little bit of entropy.
|
||||
*
|
||||
* R6000 and R6000A neither have a count register nor a random register.
|
||||
* That leaves no entropy source in the CPU itself.
|
||||
*/
|
||||
static inline unsigned long random_get_entropy(void)
|
||||
{
|
||||
unsigned int prid = read_c0_prid();
|
||||
unsigned int imp = prid & PRID_IMP_MASK;
|
||||
|
||||
if (can_use_mips_counter(prid))
|
||||
return read_c0_count();
|
||||
else if (likely(imp != PRID_IMP_R6000 && imp != PRID_IMP_R6000A))
|
||||
return read_c0_random();
|
||||
else
|
||||
return 0; /* no usable register */
|
||||
}
|
||||
#define random_get_entropy random_get_entropy
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* _ASM_TIMEX_H */
|
||||
|
@@ -55,6 +55,9 @@ void ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b, unsigned int c)
|
||||
#define Ip_u2u1u3(op) \
|
||||
void ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b, unsigned int c)
|
||||
|
||||
#define Ip_u3u2u1(op) \
|
||||
void ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b, unsigned int c)
|
||||
|
||||
#define Ip_u3u1u2(op) \
|
||||
void ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b, unsigned int c)
|
||||
|
||||
@@ -74,6 +77,9 @@ void ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b, unsigned int c, \
|
||||
#define Ip_u1u2(op) \
|
||||
void ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b)
|
||||
|
||||
#define Ip_u2u1(op) \
|
||||
void ISAOPC(op)(u32 **buf, unsigned int a, unsigned int b)
|
||||
|
||||
#define Ip_u1s2(op) \
|
||||
void ISAOPC(op)(u32 **buf, unsigned int a, signed int b)
|
||||
|
||||
@@ -99,6 +105,7 @@ Ip_u2u1s3(_daddiu);
|
||||
Ip_u3u1u2(_daddu);
|
||||
Ip_u2u1msbu3(_dins);
|
||||
Ip_u2u1msbu3(_dinsm);
|
||||
Ip_u1u2(_divu);
|
||||
Ip_u1u2u3(_dmfc0);
|
||||
Ip_u1u2u3(_dmtc0);
|
||||
Ip_u2u1u3(_drotr);
|
||||
@@ -114,16 +121,22 @@ Ip_u2u1msbu3(_ext);
|
||||
Ip_u2u1msbu3(_ins);
|
||||
Ip_u1(_j);
|
||||
Ip_u1(_jal);
|
||||
Ip_u2u1(_jalr);
|
||||
Ip_u1(_jr);
|
||||
Ip_u2s3u1(_lb);
|
||||
Ip_u2s3u1(_ld);
|
||||
Ip_u3u1u2(_ldx);
|
||||
Ip_u2s3u1(_lh);
|
||||
Ip_u2s3u1(_ll);
|
||||
Ip_u2s3u1(_lld);
|
||||
Ip_u1s2(_lui);
|
||||
Ip_u2s3u1(_lw);
|
||||
Ip_u3u1u2(_lwx);
|
||||
Ip_u1u2u3(_mfc0);
|
||||
Ip_u1(_mfhi);
|
||||
Ip_u1(_mflo);
|
||||
Ip_u1u2u3(_mtc0);
|
||||
Ip_u3u1u2(_mul);
|
||||
Ip_u3u1u2(_or);
|
||||
Ip_u2u1u3(_ori);
|
||||
Ip_u2s3u1(_pref);
|
||||
@@ -133,17 +146,25 @@ Ip_u2s3u1(_sc);
|
||||
Ip_u2s3u1(_scd);
|
||||
Ip_u2s3u1(_sd);
|
||||
Ip_u2u1u3(_sll);
|
||||
Ip_u3u2u1(_sllv);
|
||||
Ip_u2u1s3(_sltiu);
|
||||
Ip_u3u1u2(_sltu);
|
||||
Ip_u2u1u3(_sra);
|
||||
Ip_u2u1u3(_srl);
|
||||
Ip_u3u2u1(_srlv);
|
||||
Ip_u3u1u2(_subu);
|
||||
Ip_u2s3u1(_sw);
|
||||
Ip_u1(_sync);
|
||||
Ip_u1(_syscall);
|
||||
Ip_0(_tlbp);
|
||||
Ip_0(_tlbr);
|
||||
Ip_0(_tlbwi);
|
||||
Ip_0(_tlbwr);
|
||||
Ip_u1(_wait);
|
||||
Ip_u2u1(_wsbh);
|
||||
Ip_u3u1u2(_xor);
|
||||
Ip_u2u1u3(_xori);
|
||||
Ip_u2u1(_yield);
|
||||
|
||||
|
||||
/* Handle labels. */
|
||||
@@ -264,6 +285,8 @@ void uasm_il_bbit0(u32 **p, struct uasm_reloc **r, unsigned int reg,
|
||||
unsigned int bit, int lid);
|
||||
void uasm_il_bbit1(u32 **p, struct uasm_reloc **r, unsigned int reg,
|
||||
unsigned int bit, int lid);
|
||||
void uasm_il_beq(u32 **p, struct uasm_reloc **r, unsigned int r1,
|
||||
unsigned int r2, int lid);
|
||||
void uasm_il_beqz(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
|
||||
void uasm_il_beqzl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
|
||||
void uasm_il_bgezl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
|
||||
|
Reference in New Issue
Block a user