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

mips-gic.h (12387B)


      1/* SPDX-License-Identifier: GPL-2.0-or-later */
      2/*
      3 * Copyright (C) 2017 Imagination Technologies
      4 * Author: Paul Burton <paul.burton@mips.com>
      5 */
      6
      7#ifndef __MIPS_ASM_MIPS_CPS_H__
      8# error Please include asm/mips-cps.h rather than asm/mips-gic.h
      9#endif
     10
     11#ifndef __MIPS_ASM_MIPS_GIC_H__
     12#define __MIPS_ASM_MIPS_GIC_H__
     13
     14#include <linux/bitops.h>
     15
     16/* The base address of the GIC registers */
     17extern void __iomem *mips_gic_base;
     18
     19/* Offsets from the GIC base address to various control blocks */
     20#define MIPS_GIC_SHARED_OFS	0x00000
     21#define MIPS_GIC_SHARED_SZ	0x08000
     22#define MIPS_GIC_LOCAL_OFS	0x08000
     23#define MIPS_GIC_LOCAL_SZ	0x04000
     24#define MIPS_GIC_REDIR_OFS	0x0c000
     25#define MIPS_GIC_REDIR_SZ	0x04000
     26#define MIPS_GIC_USER_OFS	0x10000
     27#define MIPS_GIC_USER_SZ	0x10000
     28
     29/* For read-only shared registers */
     30#define GIC_ACCESSOR_RO(sz, off, name)					\
     31	CPS_ACCESSOR_RO(gic, sz, MIPS_GIC_SHARED_OFS + off, name)
     32
     33/* For read-write shared registers */
     34#define GIC_ACCESSOR_RW(sz, off, name)					\
     35	CPS_ACCESSOR_RW(gic, sz, MIPS_GIC_SHARED_OFS + off, name)
     36
     37/* For read-only local registers */
     38#define GIC_VX_ACCESSOR_RO(sz, off, name)				\
     39	CPS_ACCESSOR_RO(gic, sz, MIPS_GIC_LOCAL_OFS + off, vl_##name)	\
     40	CPS_ACCESSOR_RO(gic, sz, MIPS_GIC_REDIR_OFS + off, vo_##name)
     41
     42/* For read-write local registers */
     43#define GIC_VX_ACCESSOR_RW(sz, off, name)				\
     44	CPS_ACCESSOR_RW(gic, sz, MIPS_GIC_LOCAL_OFS + off, vl_##name)	\
     45	CPS_ACCESSOR_RW(gic, sz, MIPS_GIC_REDIR_OFS + off, vo_##name)
     46
     47/* For read-only shared per-interrupt registers */
     48#define GIC_ACCESSOR_RO_INTR_REG(sz, off, stride, name)			\
     49static inline void __iomem *addr_gic_##name(unsigned int intr)		\
     50{									\
     51	return mips_gic_base + (off) + (intr * (stride));		\
     52}									\
     53									\
     54static inline unsigned int read_gic_##name(unsigned int intr)		\
     55{									\
     56	BUILD_BUG_ON(sz != 32);						\
     57	return __raw_readl(addr_gic_##name(intr));			\
     58}
     59
     60/* For read-write shared per-interrupt registers */
     61#define GIC_ACCESSOR_RW_INTR_REG(sz, off, stride, name)			\
     62	GIC_ACCESSOR_RO_INTR_REG(sz, off, stride, name)			\
     63									\
     64static inline void write_gic_##name(unsigned int intr,			\
     65				    unsigned int val)			\
     66{									\
     67	BUILD_BUG_ON(sz != 32);						\
     68	__raw_writel(val, addr_gic_##name(intr));			\
     69}
     70
     71/* For read-only local per-interrupt registers */
     72#define GIC_VX_ACCESSOR_RO_INTR_REG(sz, off, stride, name)		\
     73	GIC_ACCESSOR_RO_INTR_REG(sz, MIPS_GIC_LOCAL_OFS + off,		\
     74				 stride, vl_##name)			\
     75	GIC_ACCESSOR_RO_INTR_REG(sz, MIPS_GIC_REDIR_OFS + off,		\
     76				 stride, vo_##name)
     77
     78/* For read-write local per-interrupt registers */
     79#define GIC_VX_ACCESSOR_RW_INTR_REG(sz, off, stride, name)		\
     80	GIC_ACCESSOR_RW_INTR_REG(sz, MIPS_GIC_LOCAL_OFS + off,		\
     81				 stride, vl_##name)			\
     82	GIC_ACCESSOR_RW_INTR_REG(sz, MIPS_GIC_REDIR_OFS + off,		\
     83				 stride, vo_##name)
     84
     85/* For read-only shared bit-per-interrupt registers */
     86#define GIC_ACCESSOR_RO_INTR_BIT(off, name)				\
     87static inline void __iomem *addr_gic_##name(void)			\
     88{									\
     89	return mips_gic_base + (off);					\
     90}									\
     91									\
     92static inline unsigned int read_gic_##name(unsigned int intr)		\
     93{									\
     94	void __iomem *addr = addr_gic_##name();				\
     95	unsigned int val;						\
     96									\
     97	if (mips_cm_is64) {						\
     98		addr += (intr / 64) * sizeof(uint64_t);			\
     99		val = __raw_readq(addr) >> intr % 64;			\
    100	} else {							\
    101		addr += (intr / 32) * sizeof(uint32_t);			\
    102		val = __raw_readl(addr) >> intr % 32;			\
    103	}								\
    104									\
    105	return val & 0x1;						\
    106}
    107
    108/* For read-write shared bit-per-interrupt registers */
    109#define GIC_ACCESSOR_RW_INTR_BIT(off, name)				\
    110	GIC_ACCESSOR_RO_INTR_BIT(off, name)				\
    111									\
    112static inline void write_gic_##name(unsigned int intr)			\
    113{									\
    114	void __iomem *addr = addr_gic_##name();				\
    115									\
    116	if (mips_cm_is64) {						\
    117		addr += (intr / 64) * sizeof(uint64_t);			\
    118		__raw_writeq(BIT(intr % 64), addr);			\
    119	} else {							\
    120		addr += (intr / 32) * sizeof(uint32_t);			\
    121		__raw_writel(BIT(intr % 32), addr);			\
    122	}								\
    123}									\
    124									\
    125static inline void change_gic_##name(unsigned int intr,			\
    126				     unsigned int val)			\
    127{									\
    128	void __iomem *addr = addr_gic_##name();				\
    129									\
    130	if (mips_cm_is64) {						\
    131		uint64_t _val;						\
    132									\
    133		addr += (intr / 64) * sizeof(uint64_t);			\
    134		_val = __raw_readq(addr);				\
    135		_val &= ~BIT_ULL(intr % 64);				\
    136		_val |= (uint64_t)val << (intr % 64);			\
    137		__raw_writeq(_val, addr);				\
    138	} else {							\
    139		uint32_t _val;						\
    140									\
    141		addr += (intr / 32) * sizeof(uint32_t);			\
    142		_val = __raw_readl(addr);				\
    143		_val &= ~BIT(intr % 32);				\
    144		_val |= val << (intr % 32);				\
    145		__raw_writel(_val, addr);				\
    146	}								\
    147}
    148
    149/* For read-only local bit-per-interrupt registers */
    150#define GIC_VX_ACCESSOR_RO_INTR_BIT(sz, off, name)			\
    151	GIC_ACCESSOR_RO_INTR_BIT(sz, MIPS_GIC_LOCAL_OFS + off,		\
    152				 vl_##name)				\
    153	GIC_ACCESSOR_RO_INTR_BIT(sz, MIPS_GIC_REDIR_OFS + off,		\
    154				 vo_##name)
    155
    156/* For read-write local bit-per-interrupt registers */
    157#define GIC_VX_ACCESSOR_RW_INTR_BIT(sz, off, name)			\
    158	GIC_ACCESSOR_RW_INTR_BIT(sz, MIPS_GIC_LOCAL_OFS + off,		\
    159				 vl_##name)				\
    160	GIC_ACCESSOR_RW_INTR_BIT(sz, MIPS_GIC_REDIR_OFS + off,		\
    161				 vo_##name)
    162
    163/* GIC_SH_CONFIG - Information about the GIC configuration */
    164GIC_ACCESSOR_RW(32, 0x000, config)
    165#define GIC_CONFIG_COUNTSTOP		BIT(28)
    166#define GIC_CONFIG_COUNTBITS		GENMASK(27, 24)
    167#define GIC_CONFIG_NUMINTERRUPTS	GENMASK(23, 16)
    168#define GIC_CONFIG_PVPS			GENMASK(6, 0)
    169
    170/* GIC_SH_COUNTER - Shared global counter value */
    171GIC_ACCESSOR_RW(64, 0x010, counter)
    172GIC_ACCESSOR_RW(32, 0x010, counter_32l)
    173GIC_ACCESSOR_RW(32, 0x014, counter_32h)
    174
    175/* GIC_SH_POL_* - Configures interrupt polarity */
    176GIC_ACCESSOR_RW_INTR_BIT(0x100, pol)
    177#define GIC_POL_ACTIVE_LOW		0	/* when level triggered */
    178#define GIC_POL_ACTIVE_HIGH		1	/* when level triggered */
    179#define GIC_POL_FALLING_EDGE		0	/* when single-edge triggered */
    180#define GIC_POL_RISING_EDGE		1	/* when single-edge triggered */
    181
    182/* GIC_SH_TRIG_* - Configures interrupts to be edge or level triggered */
    183GIC_ACCESSOR_RW_INTR_BIT(0x180, trig)
    184#define GIC_TRIG_LEVEL			0
    185#define GIC_TRIG_EDGE			1
    186
    187/* GIC_SH_DUAL_* - Configures whether interrupts trigger on both edges */
    188GIC_ACCESSOR_RW_INTR_BIT(0x200, dual)
    189#define GIC_DUAL_SINGLE			0	/* when edge-triggered */
    190#define GIC_DUAL_DUAL			1	/* when edge-triggered */
    191
    192/* GIC_SH_WEDGE - Write an 'edge', ie. trigger an interrupt */
    193GIC_ACCESSOR_RW(32, 0x280, wedge)
    194#define GIC_WEDGE_RW			BIT(31)
    195#define GIC_WEDGE_INTR			GENMASK(7, 0)
    196
    197/* GIC_SH_RMASK_* - Reset/clear shared interrupt mask bits */
    198GIC_ACCESSOR_RW_INTR_BIT(0x300, rmask)
    199
    200/* GIC_SH_SMASK_* - Set shared interrupt mask bits */
    201GIC_ACCESSOR_RW_INTR_BIT(0x380, smask)
    202
    203/* GIC_SH_MASK_* - Read the current shared interrupt mask */
    204GIC_ACCESSOR_RO_INTR_BIT(0x400, mask)
    205
    206/* GIC_SH_PEND_* - Read currently pending shared interrupts */
    207GIC_ACCESSOR_RO_INTR_BIT(0x480, pend)
    208
    209/* GIC_SH_MAPx_PIN - Map shared interrupts to a particular CPU pin */
    210GIC_ACCESSOR_RW_INTR_REG(32, 0x500, 0x4, map_pin)
    211#define GIC_MAP_PIN_MAP_TO_PIN		BIT(31)
    212#define GIC_MAP_PIN_MAP_TO_NMI		BIT(30)
    213#define GIC_MAP_PIN_MAP			GENMASK(5, 0)
    214
    215/* GIC_SH_MAPx_VP - Map shared interrupts to a particular Virtual Processor */
    216GIC_ACCESSOR_RW_INTR_REG(32, 0x2000, 0x20, map_vp)
    217
    218/* GIC_Vx_CTL - VP-level interrupt control */
    219GIC_VX_ACCESSOR_RW(32, 0x000, ctl)
    220#define GIC_VX_CTL_FDC_ROUTABLE		BIT(4)
    221#define GIC_VX_CTL_SWINT_ROUTABLE	BIT(3)
    222#define GIC_VX_CTL_PERFCNT_ROUTABLE	BIT(2)
    223#define GIC_VX_CTL_TIMER_ROUTABLE	BIT(1)
    224#define GIC_VX_CTL_EIC			BIT(0)
    225
    226/* GIC_Vx_PEND - Read currently pending local interrupts */
    227GIC_VX_ACCESSOR_RO(32, 0x004, pend)
    228
    229/* GIC_Vx_MASK - Read the current local interrupt mask */
    230GIC_VX_ACCESSOR_RO(32, 0x008, mask)
    231
    232/* GIC_Vx_RMASK - Reset/clear local interrupt mask bits */
    233GIC_VX_ACCESSOR_RW(32, 0x00c, rmask)
    234
    235/* GIC_Vx_SMASK - Set local interrupt mask bits */
    236GIC_VX_ACCESSOR_RW(32, 0x010, smask)
    237
    238/* GIC_Vx_*_MAP - Route local interrupts to the desired pins */
    239GIC_VX_ACCESSOR_RW_INTR_REG(32, 0x040, 0x4, map)
    240
    241/* GIC_Vx_WD_MAP - Route the local watchdog timer interrupt */
    242GIC_VX_ACCESSOR_RW(32, 0x040, wd_map)
    243
    244/* GIC_Vx_COMPARE_MAP - Route the local count/compare interrupt */
    245GIC_VX_ACCESSOR_RW(32, 0x044, compare_map)
    246
    247/* GIC_Vx_TIMER_MAP - Route the local CPU timer (cp0 count/compare) interrupt */
    248GIC_VX_ACCESSOR_RW(32, 0x048, timer_map)
    249
    250/* GIC_Vx_FDC_MAP - Route the local fast debug channel interrupt */
    251GIC_VX_ACCESSOR_RW(32, 0x04c, fdc_map)
    252
    253/* GIC_Vx_PERFCTR_MAP - Route the local performance counter interrupt */
    254GIC_VX_ACCESSOR_RW(32, 0x050, perfctr_map)
    255
    256/* GIC_Vx_SWINT0_MAP - Route the local software interrupt 0 */
    257GIC_VX_ACCESSOR_RW(32, 0x054, swint0_map)
    258
    259/* GIC_Vx_SWINT1_MAP - Route the local software interrupt 1 */
    260GIC_VX_ACCESSOR_RW(32, 0x058, swint1_map)
    261
    262/* GIC_Vx_OTHER - Configure access to other Virtual Processor registers */
    263GIC_VX_ACCESSOR_RW(32, 0x080, other)
    264#define GIC_VX_OTHER_VPNUM		GENMASK(5, 0)
    265
    266/* GIC_Vx_IDENT - Retrieve the local Virtual Processor's ID */
    267GIC_VX_ACCESSOR_RO(32, 0x088, ident)
    268#define GIC_VX_IDENT_VPNUM		GENMASK(5, 0)
    269
    270/* GIC_Vx_COMPARE - Value to compare with GIC_SH_COUNTER */
    271GIC_VX_ACCESSOR_RW(64, 0x0a0, compare)
    272
    273/* GIC_Vx_EIC_SHADOW_SET_BASE - Set shadow register set for each interrupt */
    274GIC_VX_ACCESSOR_RW_INTR_REG(32, 0x100, 0x4, eic_shadow_set)
    275
    276/**
    277 * enum mips_gic_local_interrupt - GIC local interrupts
    278 * @GIC_LOCAL_INT_WD: GIC watchdog timer interrupt
    279 * @GIC_LOCAL_INT_COMPARE: GIC count/compare interrupt
    280 * @GIC_LOCAL_INT_TIMER: CP0 count/compare interrupt
    281 * @GIC_LOCAL_INT_PERFCTR: Performance counter interrupt
    282 * @GIC_LOCAL_INT_SWINT0: Software interrupt 0
    283 * @GIC_LOCAL_INT_SWINT1: Software interrupt 1
    284 * @GIC_LOCAL_INT_FDC: Fast debug channel interrupt
    285 * @GIC_NUM_LOCAL_INTRS: The number of local interrupts
    286 *
    287 * Enumerates interrupts provided by the GIC that are local to a VP.
    288 */
    289enum mips_gic_local_interrupt {
    290	GIC_LOCAL_INT_WD,
    291	GIC_LOCAL_INT_COMPARE,
    292	GIC_LOCAL_INT_TIMER,
    293	GIC_LOCAL_INT_PERFCTR,
    294	GIC_LOCAL_INT_SWINT0,
    295	GIC_LOCAL_INT_SWINT1,
    296	GIC_LOCAL_INT_FDC,
    297	GIC_NUM_LOCAL_INTRS
    298};
    299
    300/**
    301 * mips_gic_present() - Determine whether a GIC is present
    302 *
    303 * Determines whether a MIPS Global Interrupt Controller (GIC) is present in
    304 * the system that the kernel is running on.
    305 *
    306 * Return true if a GIC is present, else false.
    307 */
    308static inline bool mips_gic_present(void)
    309{
    310	return IS_ENABLED(CONFIG_MIPS_GIC) && mips_gic_base;
    311}
    312
    313/**
    314 * mips_gic_vx_map_reg() - Return GIC_Vx_<intr>_MAP register offset
    315 * @intr: A GIC local interrupt
    316 *
    317 * Determine the index of the GIC_VL_<intr>_MAP or GIC_VO_<intr>_MAP register
    318 * within the block of GIC map registers. This is almost the same as the order
    319 * of interrupts in the pending & mask registers, as used by enum
    320 * mips_gic_local_interrupt, but moves the FDC interrupt & thus offsets the
    321 * interrupts after it...
    322 *
    323 * Return: The map register index corresponding to @intr.
    324 *
    325 * The return value is suitable for use with the (read|write)_gic_v[lo]_map
    326 * accessor functions.
    327 */
    328static inline unsigned int
    329mips_gic_vx_map_reg(enum mips_gic_local_interrupt intr)
    330{
    331	/* WD, Compare & Timer are 1:1 */
    332	if (intr <= GIC_LOCAL_INT_TIMER)
    333		return intr;
    334
    335	/* FDC moves to after Timer... */
    336	if (intr == GIC_LOCAL_INT_FDC)
    337		return GIC_LOCAL_INT_TIMER + 1;
    338
    339	/* As a result everything else is offset by 1 */
    340	return intr + 1;
    341}
    342
    343/**
    344 * gic_get_c0_compare_int() - Return cp0 count/compare interrupt virq
    345 *
    346 * Determine the virq number to use for the coprocessor 0 count/compare
    347 * interrupt, which may be routed via the GIC.
    348 *
    349 * Returns the virq number or a negative error number.
    350 */
    351extern int gic_get_c0_compare_int(void);
    352
    353/**
    354 * gic_get_c0_perfcount_int() - Return performance counter interrupt virq
    355 *
    356 * Determine the virq number to use for CPU performance counter interrupts,
    357 * which may be routed via the GIC.
    358 *
    359 * Returns the virq number or a negative error number.
    360 */
    361extern int gic_get_c0_perfcount_int(void);
    362
    363/**
    364 * gic_get_c0_fdc_int() - Return fast debug channel interrupt virq
    365 *
    366 * Determine the virq number to use for fast debug channel (FDC) interrupts,
    367 * which may be routed via the GIC.
    368 *
    369 * Returns the virq number or a negative error number.
    370 */
    371extern int gic_get_c0_fdc_int(void);
    372
    373#endif /* __MIPS_ASM_MIPS_CPS_H__ */