arch/mips/sgi-ip30/ip30-smp.c

Source file repositories/reference/linux-study-clean/arch/mips/sgi-ip30/ip30-smp.c

File Facts

System
Linux kernel
Corpus path
arch/mips/sgi-ip30/ip30-smp.c
Extension
.c
Size
3542 bytes
Lines
150
Domain
Architecture Layer
Bucket
arch/mips
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

struct mpconf {
	u32 magic;
	u32 prid;
	u32 physid;
	u32 virtid;
	u32 scachesz;
	u16 fanloads;
	u16 res;
	void *launch;
	void *rendezvous;
	u64 res2[3];
	void *stackaddr;
	void *lnch_parm;
	void *rndv_parm;
	u32 idleflag;
};

static void ip30_smp_send_ipi_single(int cpu, u32 action)
{
	int irq;

	switch (action) {
	case SMP_RESCHEDULE_YOURSELF:
		irq = HEART_L2_INT_RESCHED_CPU_0;
		break;
	case SMP_CALL_FUNCTION:
		irq = HEART_L2_INT_CALL_CPU_0;
		break;
	default:
		panic("IP30: Unknown action value in %s!\n", __func__);
	}

	irq += cpu;

	/* Poke the other CPU -- it's got mail! */
	heart_write(BIT_ULL(irq), &heart_regs->set_isr);
}

static void ip30_smp_send_ipi_mask(const struct cpumask *mask, u32 action)
{
	u32 i;

	for_each_cpu(i, mask)
		ip30_smp_send_ipi_single(i, action);
}

static void __init ip30_smp_setup(void)
{
	int i;
	int ncpu = 0;
	struct mpconf *mpc;

	init_cpu_possible(cpumask_of(0));

	/* Scan the MPCONF structure and enumerate available CPUs. */
	for (i = 0; i < MP_NCPU; i++) {
		mpc = (struct mpconf *)MPCONF(i);
		if (mpc->magic == MPCONF_MAGIC) {
			set_cpu_possible(i, true);
			__cpu_number_map[i] = ++ncpu;
			__cpu_logical_map[ncpu] = i;
			pr_info("IP30: Slot: %d, PrID: %.8x, PhyID: %d, VirtID: %d\n",
				i, mpc->prid, mpc->physid, mpc->virtid);
		}
	}
	pr_info("IP30: Detected %d CPU(s) present.\n", ncpu);

	/*
	 * Set the coherency algorithm to '5' (cacheable coherent
	 * exclusive on write).  This is needed on IP30 SMP, especially
	 * for R14000 CPUs, otherwise, instruction bus errors will
	 * occur upon reaching userland.
	 */
	change_c0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_COW);
}

static void __init ip30_smp_prepare_cpus(unsigned int max_cpus)
{
	/* nothing to do here */
}

static int __init ip30_smp_boot_secondary(int cpu, struct task_struct *idle)
{
	struct mpconf *mpc = (struct mpconf *)MPCONF(cpu);

	/* Stack pointer (sp). */
	mpc->stackaddr = (void *)__KSTK_TOS(idle);

	/* Global pointer (gp). */
	mpc->lnch_parm = task_thread_info(idle);

Annotation

Implementation Notes