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

smp.c (2540B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 *  PS3 SMP routines.
      4 *
      5 *  Copyright (C) 2006 Sony Computer Entertainment Inc.
      6 *  Copyright 2006 Sony Corp.
      7 */
      8
      9#include <linux/kernel.h>
     10#include <linux/smp.h>
     11
     12#include <asm/machdep.h>
     13#include <asm/udbg.h>
     14
     15#include "platform.h"
     16
     17#if defined(DEBUG)
     18#define DBG udbg_printf
     19#else
     20#define DBG pr_debug
     21#endif
     22
     23/**
     24  * ps3_ipi_virqs - a per cpu array of virqs for ipi use
     25  */
     26
     27#define MSG_COUNT 4
     28static DEFINE_PER_CPU(unsigned int [MSG_COUNT], ps3_ipi_virqs);
     29
     30static void ps3_smp_message_pass(int cpu, int msg)
     31{
     32	int result;
     33	unsigned int virq;
     34
     35	if (msg >= MSG_COUNT) {
     36		DBG("%s:%d: bad msg: %d\n", __func__, __LINE__, msg);
     37		return;
     38	}
     39
     40	virq = per_cpu(ps3_ipi_virqs, cpu)[msg];
     41	result = ps3_send_event_locally(virq);
     42
     43	if (result)
     44		DBG("%s:%d: ps3_send_event_locally(%d, %d) failed"
     45			" (%d)\n", __func__, __LINE__, cpu, msg, result);
     46}
     47
     48static void __init ps3_smp_probe(void)
     49{
     50	int cpu;
     51
     52	for (cpu = 0; cpu < 2; cpu++) {
     53		int result;
     54		unsigned int *virqs = per_cpu(ps3_ipi_virqs, cpu);
     55		int i;
     56
     57		DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu);
     58
     59		/*
     60		* Check assumptions on ps3_ipi_virqs[] indexing. If this
     61		* check fails, then a different mapping of PPC_MSG_
     62		* to index needs to be setup.
     63		*/
     64
     65		BUILD_BUG_ON(PPC_MSG_CALL_FUNCTION    != 0);
     66		BUILD_BUG_ON(PPC_MSG_RESCHEDULE       != 1);
     67		BUILD_BUG_ON(PPC_MSG_TICK_BROADCAST   != 2);
     68		BUILD_BUG_ON(PPC_MSG_NMI_IPI          != 3);
     69
     70		for (i = 0; i < MSG_COUNT; i++) {
     71			result = ps3_event_receive_port_setup(cpu, &virqs[i]);
     72
     73			if (result)
     74				continue;
     75
     76			DBG("%s:%d: (%d, %d) => virq %u\n",
     77				__func__, __LINE__, cpu, i, virqs[i]);
     78
     79			result = smp_request_message_ipi(virqs[i], i);
     80
     81			if (result)
     82				virqs[i] = 0;
     83			else
     84				ps3_register_ipi_irq(cpu, virqs[i]);
     85		}
     86
     87		ps3_register_ipi_debug_brk(cpu, virqs[PPC_MSG_NMI_IPI]);
     88
     89		DBG(" <- %s:%d: (%d)\n", __func__, __LINE__, cpu);
     90	}
     91}
     92
     93void ps3_smp_cleanup_cpu(int cpu)
     94{
     95	unsigned int *virqs = per_cpu(ps3_ipi_virqs, cpu);
     96	int i;
     97
     98	DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu);
     99
    100	for (i = 0; i < MSG_COUNT; i++) {
    101		/* Can't call free_irq from interrupt context. */
    102		ps3_event_receive_port_destroy(virqs[i]);
    103		virqs[i] = 0;
    104	}
    105
    106	DBG(" <- %s:%d: (%d)\n", __func__, __LINE__, cpu);
    107}
    108
    109static struct smp_ops_t ps3_smp_ops = {
    110	.probe		= ps3_smp_probe,
    111	.message_pass	= ps3_smp_message_pass,
    112	.kick_cpu	= smp_generic_kick_cpu,
    113};
    114
    115void __init smp_init_ps3(void)
    116{
    117	DBG(" -> %s\n", __func__);
    118	smp_ops = &ps3_smp_ops;
    119	DBG(" <- %s\n", __func__);
    120}