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

xics.h (4539B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2/*
      3 * Common definitions across all variants of ICP and ICS interrupt
      4 * controllers.
      5 */
      6
      7#ifndef _XICS_H
      8#define _XICS_H
      9
     10#include <linux/interrupt.h>
     11
     12#define XICS_IPI		2
     13#define XICS_IRQ_SPURIOUS	0
     14
     15/* Want a priority other than 0.  Various HW issues require this. */
     16#define	DEFAULT_PRIORITY	5
     17
     18/*
     19 * Mark IPIs as higher priority so we can take them inside interrupts
     20 * FIXME: still true now?
     21 */
     22#define IPI_PRIORITY		4
     23
     24/* The least favored priority */
     25#define LOWEST_PRIORITY		0xFF
     26
     27/* The number of priorities defined above */
     28#define MAX_NUM_PRIORITIES	3
     29
     30/* Native ICP */
     31#ifdef CONFIG_PPC_ICP_NATIVE
     32extern int icp_native_init(void);
     33extern void icp_native_flush_interrupt(void);
     34extern void icp_native_cause_ipi_rm(int cpu);
     35#else
     36static inline int icp_native_init(void) { return -ENODEV; }
     37#endif
     38
     39/* PAPR ICP */
     40#ifdef CONFIG_PPC_ICP_HV
     41int __init icp_hv_init(void);
     42#else
     43static inline int icp_hv_init(void) { return -ENODEV; }
     44#endif
     45
     46#ifdef CONFIG_PPC_POWERNV
     47int __init icp_opal_init(void);
     48extern void icp_opal_flush_interrupt(void);
     49#else
     50static inline int icp_opal_init(void) { return -ENODEV; }
     51#endif
     52
     53/* ICP ops */
     54struct icp_ops {
     55	unsigned int (*get_irq)(void);
     56	void (*eoi)(struct irq_data *d);
     57	void (*set_priority)(unsigned char prio);
     58	void (*teardown_cpu)(void);
     59	void (*flush_ipi)(void);
     60#ifdef CONFIG_SMP
     61	void (*cause_ipi)(int cpu);
     62	irq_handler_t ipi_action;
     63#endif
     64};
     65
     66extern const struct icp_ops *icp_ops;
     67
     68#ifdef CONFIG_PPC_ICS_NATIVE
     69/* Native ICS */
     70extern int ics_native_init(void);
     71#else
     72static inline int ics_native_init(void) { return -ENODEV; }
     73#endif
     74
     75/* RTAS ICS */
     76#ifdef CONFIG_PPC_ICS_RTAS
     77extern int ics_rtas_init(void);
     78#else
     79static inline int ics_rtas_init(void) { return -ENODEV; }
     80#endif
     81
     82/* HAL ICS */
     83#ifdef CONFIG_PPC_POWERNV
     84extern int ics_opal_init(void);
     85#else
     86static inline int ics_opal_init(void) { return -ENODEV; }
     87#endif
     88
     89/* ICS instance, hooked up to chip_data of an irq */
     90struct ics {
     91	struct list_head link;
     92	int (*check)(struct ics *ics, unsigned int hwirq);
     93	void (*mask_unknown)(struct ics *ics, unsigned long vec);
     94	long (*get_server)(struct ics *ics, unsigned long vec);
     95	int (*host_match)(struct ics *ics, struct device_node *node);
     96	struct irq_chip *chip;
     97	char data[];
     98};
     99
    100/* Commons */
    101extern unsigned int xics_default_server;
    102extern unsigned int xics_default_distrib_server;
    103extern unsigned int xics_interrupt_server_size;
    104extern struct irq_domain *xics_host;
    105
    106struct xics_cppr {
    107	unsigned char stack[MAX_NUM_PRIORITIES];
    108	int index;
    109};
    110
    111DECLARE_PER_CPU(struct xics_cppr, xics_cppr);
    112
    113static inline void xics_push_cppr(unsigned int vec)
    114{
    115	struct xics_cppr *os_cppr = this_cpu_ptr(&xics_cppr);
    116
    117	if (WARN_ON(os_cppr->index >= MAX_NUM_PRIORITIES - 1))
    118		return;
    119
    120	if (vec == XICS_IPI)
    121		os_cppr->stack[++os_cppr->index] = IPI_PRIORITY;
    122	else
    123		os_cppr->stack[++os_cppr->index] = DEFAULT_PRIORITY;
    124}
    125
    126static inline unsigned char xics_pop_cppr(void)
    127{
    128	struct xics_cppr *os_cppr = this_cpu_ptr(&xics_cppr);
    129
    130	if (WARN_ON(os_cppr->index < 1))
    131		return LOWEST_PRIORITY;
    132
    133	return os_cppr->stack[--os_cppr->index];
    134}
    135
    136static inline void xics_set_base_cppr(unsigned char cppr)
    137{
    138	struct xics_cppr *os_cppr = this_cpu_ptr(&xics_cppr);
    139
    140	/* we only really want to set the priority when there's
    141	 * just one cppr value on the stack
    142	 */
    143	WARN_ON(os_cppr->index != 0);
    144
    145	os_cppr->stack[0] = cppr;
    146}
    147
    148static inline unsigned char xics_cppr_top(void)
    149{
    150	struct xics_cppr *os_cppr = this_cpu_ptr(&xics_cppr);
    151	
    152	return os_cppr->stack[os_cppr->index];
    153}
    154
    155DECLARE_PER_CPU_SHARED_ALIGNED(unsigned long, xics_ipi_message);
    156
    157extern void xics_init(void);
    158extern void xics_setup_cpu(void);
    159extern void xics_update_irq_servers(void);
    160extern void xics_set_cpu_giq(unsigned int gserver, unsigned int join);
    161extern void xics_mask_unknown_vec(unsigned int vec);
    162extern irqreturn_t xics_ipi_dispatch(int cpu);
    163extern void xics_smp_probe(void);
    164extern void xics_register_ics(struct ics *ics);
    165extern void xics_teardown_cpu(void);
    166extern void xics_kexec_teardown_cpu(int secondary);
    167extern void xics_migrate_irqs_away(void);
    168extern void icp_native_eoi(struct irq_data *d);
    169extern int xics_set_irq_type(struct irq_data *d, unsigned int flow_type);
    170extern int xics_retrigger(struct irq_data *data);
    171#ifdef CONFIG_SMP
    172extern int xics_get_irq_server(unsigned int virq, const struct cpumask *cpumask,
    173			       unsigned int strict_check);
    174#else
    175#define xics_get_irq_server(virq, cpumask, strict_check) (xics_default_server)
    176#endif
    177
    178
    179#endif /* _XICS_H */