/* Copyright (C) 2004 Mips Technologies, Inc */
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/cpumask.h>
#include <linux/interrupt.h>
#include <asm/cpu.h>
#include <asm/processor.h>
#include <asm/atomic.h>
#include <asm/system.h>
#include <asm/hardirq.h>
#include <asm/hazards.h>
#include <asm/mmu_context.h>
#include <asm/smp.h>
#include <asm/mipsregs.h>
#include <asm/cacheflush.h>
#include <asm/time.h>
#include <asm/addrspace.h>
#include <asm/smtc.h>
#include <asm/smtc_ipi.h>
#include <asm/smtc_proc.h>
/*
* This file should be built into the kernel only if CONFIG_MIPS_MT_SMTC is set.
*/
/*
* MIPSCPU_INT_BASE is identically defined in both
* asm-mips/mips-boards/maltaint.h and asm-mips/mips-boards/simint.h,
* but as yet there's no properly organized include structure that
* will ensure that the right *int.h file will be included for a
* given platform build.
*/
#define MIPSCPU_INT_BASE 16
#define MIPS_CPU_IPI_IRQ 1
#define LOCK_MT_PRA() \
local_irq_save(flags); \
mtflags = dmt()
#define UNLOCK_MT_PRA() \
emt(mtflags); \
local_irq_restore(flags)
#define LOCK_CORE_PRA() \
local_irq_save(flags); \
mtflags = dvpe()
#define UNLOCK_CORE_PRA() \
evpe(mtflags); \
local_irq_restore(flags)
/*
* Data structures purely associated with SMTC parallelism
*/
/*
* Table for tracking ASIDs whose lifetime is prolonged.
*/
asiduse smtc_live_asid[MAX_SMTC_TLBS][MAX_SMTC_ASIDS];
/*
* Clock interrupt "latch" buffers, per "CPU"
*/
unsigned int ipi_timer_latch[NR_CPUS];
/*
* Number of InterProcessor Interupt (IPI) message buffers to allocate
*/
#define IPIBUF_PER_CPU 4
struct smtc_ipi_q IPIQ[NR_CPUS];
struct smtc_ipi_q freeIPIq;
/* Forward declarations */
void ipi_decode(struct pt_regs *, struct smtc_ipi *);
void post_direct_ipi(int cpu, struct smtc_ipi *pipi);
void setup_cross_vpe_interrupts(void);
void init_smtc_stats(void);
/* Global SMTC Status */
unsigned int smtc_status = 0;
/* Boot command line configuration overrides */
static int vpelimit = 0;
static int tclimit = 0;
static int ipibuffers = 0;
static int nostlb = 0;
static int asidmask = 0;
unsigned long smtc_asid_mask = 0xff;
static int __init maxvpes(char *str)
{
get_option(&str, &vpelimit);
return 1;
}
static int __init maxtcs(char *str)
{
get_option(&str, &tclimit);
return 1;
}
static int __init ipibufs(char *str)
{
get_option(&str, &ipibuffers);
return 1;
}
static int __init stlb_disable(char *s)
{
nostlb = 1;
return 1;
}
static int __init