cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ip27-smp.c (4380B)


      1/*
      2 * This file is subject to the terms and conditions of the GNU General
      3 * Public License.  See the file "COPYING" in the main directory of this
      4 * archive for more details.
      5 *
      6 * Copyright (C) 2000 - 2001 by Kanoj Sarcar (kanoj@sgi.com)
      7 * Copyright (C) 2000 - 2001 by Silicon Graphics, Inc.
      8 */
      9#include <linux/init.h>
     10#include <linux/sched.h>
     11#include <linux/sched/task_stack.h>
     12#include <linux/topology.h>
     13#include <linux/nodemask.h>
     14
     15#include <asm/page.h>
     16#include <asm/processor.h>
     17#include <asm/ptrace.h>
     18#include <asm/sn/agent.h>
     19#include <asm/sn/arch.h>
     20#include <asm/sn/gda.h>
     21#include <asm/sn/intr.h>
     22#include <asm/sn/klconfig.h>
     23#include <asm/sn/launch.h>
     24#include <asm/sn/mapped_kernel.h>
     25#include <asm/sn/types.h>
     26
     27#include "ip27-common.h"
     28
     29static int node_scan_cpus(nasid_t nasid, int highest)
     30{
     31	static int cpus_found;
     32	lboard_t *brd;
     33	klcpu_t *acpu;
     34	cpuid_t cpuid;
     35
     36	brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27);
     37
     38	do {
     39		acpu = (klcpu_t *)find_first_component(brd, KLSTRUCT_CPU);
     40		while (acpu) {
     41			cpuid = acpu->cpu_info.virtid;
     42			/* Only let it join in if it's marked enabled */
     43			if ((acpu->cpu_info.flags & KLINFO_ENABLE) &&
     44			    (cpus_found != NR_CPUS)) {
     45				if (cpuid > highest)
     46					highest = cpuid;
     47				set_cpu_possible(cpuid, true);
     48				cputonasid(cpus_found) = nasid;
     49				cputoslice(cpus_found) = acpu->cpu_info.physid;
     50				sn_cpu_info[cpus_found].p_speed =
     51							acpu->cpu_speed;
     52				cpus_found++;
     53			}
     54			acpu = (klcpu_t *)find_component(brd, (klinfo_t *)acpu,
     55								KLSTRUCT_CPU);
     56		}
     57		brd = KLCF_NEXT(brd);
     58		if (!brd)
     59			break;
     60
     61		brd = find_lboard(brd, KLTYPE_IP27);
     62	} while (brd);
     63
     64	return highest;
     65}
     66
     67void cpu_node_probe(void)
     68{
     69	int i, highest = 0;
     70	gda_t *gdap = GDA;
     71
     72	nodes_clear(node_online_map);
     73	for (i = 0; i < MAX_NUMNODES; i++) {
     74		nasid_t nasid = gdap->g_nasidtable[i];
     75		if (nasid == INVALID_NASID)
     76			break;
     77		node_set_online(nasid);
     78		highest = node_scan_cpus(nasid, highest);
     79	}
     80
     81	printk("Discovered %d cpus on %d nodes\n", highest + 1, num_online_nodes());
     82}
     83
     84static __init void intr_clear_all(nasid_t nasid)
     85{
     86	int i;
     87
     88	REMOTE_HUB_S(nasid, PI_INT_MASK0_A, 0);
     89	REMOTE_HUB_S(nasid, PI_INT_MASK0_B, 0);
     90	REMOTE_HUB_S(nasid, PI_INT_MASK1_A, 0);
     91	REMOTE_HUB_S(nasid, PI_INT_MASK1_B, 0);
     92
     93	for (i = 0; i < 128; i++)
     94		REMOTE_HUB_CLR_INTR(nasid, i);
     95}
     96
     97static void ip27_send_ipi_single(int destid, unsigned int action)
     98{
     99	int irq;
    100
    101	switch (action) {
    102	case SMP_RESCHEDULE_YOURSELF:
    103		irq = CPU_RESCHED_A_IRQ;
    104		break;
    105	case SMP_CALL_FUNCTION:
    106		irq = CPU_CALL_A_IRQ;
    107		break;
    108	default:
    109		panic("sendintr");
    110	}
    111
    112	irq += cputoslice(destid);
    113
    114	/*
    115	 * Set the interrupt bit associated with the CPU we want to
    116	 * send the interrupt to.
    117	 */
    118	REMOTE_HUB_SEND_INTR(cpu_to_node(destid), irq);
    119}
    120
    121static void ip27_send_ipi_mask(const struct cpumask *mask, unsigned int action)
    122{
    123	unsigned int i;
    124
    125	for_each_cpu(i, mask)
    126		ip27_send_ipi_single(i, action);
    127}
    128
    129static void ip27_init_cpu(void)
    130{
    131	per_cpu_init();
    132}
    133
    134static void ip27_smp_finish(void)
    135{
    136	hub_rt_clock_event_init();
    137	local_irq_enable();
    138}
    139
    140/*
    141 * Launch a slave into smp_bootstrap().	 It doesn't take an argument, and we
    142 * set sp to the kernel stack of the newly created idle process, gp to the proc
    143 * struct so that current_thread_info() will work.
    144 */
    145static int ip27_boot_secondary(int cpu, struct task_struct *idle)
    146{
    147	unsigned long gp = (unsigned long)task_thread_info(idle);
    148	unsigned long sp = __KSTK_TOS(idle);
    149
    150	LAUNCH_SLAVE(cputonasid(cpu), cputoslice(cpu),
    151		(launch_proc_t)MAPPED_KERN_RW_TO_K0(smp_bootstrap),
    152		0, (void *) sp, (void *) gp);
    153	return 0;
    154}
    155
    156static void __init ip27_smp_setup(void)
    157{
    158	nasid_t nasid;
    159
    160	for_each_online_node(nasid) {
    161		if (nasid == 0)
    162			continue;
    163		intr_clear_all(nasid);
    164	}
    165
    166	replicate_kernel_text();
    167
    168	/*
    169	 * PROM sets up system, that boot cpu is always first CPU on nasid 0
    170	 */
    171	cputonasid(0) = 0;
    172	cputoslice(0) = LOCAL_HUB_L(PI_CPU_NUM);
    173}
    174
    175static void __init ip27_prepare_cpus(unsigned int max_cpus)
    176{
    177	/* We already did everything necessary earlier */
    178}
    179
    180const struct plat_smp_ops ip27_smp_ops = {
    181	.send_ipi_single	= ip27_send_ipi_single,
    182	.send_ipi_mask		= ip27_send_ipi_mask,
    183	.init_secondary		= ip27_init_cpu,
    184	.smp_finish		= ip27_smp_finish,
    185	.boot_secondary		= ip27_boot_secondary,
    186	.smp_setup		= ip27_smp_setup,
    187	.prepare_cpus		= ip27_prepare_cpus,
    188	.prepare_boot_cpu	= ip27_init_cpu,
    189};