linux/arch/arm64/include/asm/arch_gicv3.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-only */
   2/*
   3 * arch/arm64/include/asm/arch_gicv3.h
   4 *
   5 * Copyright (C) 2015 ARM Ltd.
   6 */
   7#ifndef __ASM_ARCH_GICV3_H
   8#define __ASM_ARCH_GICV3_H
   9
  10#include <asm/sysreg.h>
  11
  12#ifndef __ASSEMBLY__
  13
  14#include <linux/irqchip/arm-gic-common.h>
  15#include <linux/stringify.h>
  16#include <asm/barrier.h>
  17#include <asm/cacheflush.h>
  18
  19#define read_gicreg(r)                  read_sysreg_s(SYS_ ## r)
  20#define write_gicreg(v, r)              write_sysreg_s(v, SYS_ ## r)
  21
  22/*
  23 * Low-level accessors
  24 *
  25 * These system registers are 32 bits, but we make sure that the compiler
  26 * sets the GP register's most significant bits to 0 with an explicit cast.
  27 */
  28
  29static inline void gic_write_eoir(u32 irq)
  30{
  31        write_sysreg_s(irq, SYS_ICC_EOIR1_EL1);
  32        isb();
  33}
  34
  35static __always_inline void gic_write_dir(u32 irq)
  36{
  37        write_sysreg_s(irq, SYS_ICC_DIR_EL1);
  38        isb();
  39}
  40
  41static inline u64 gic_read_iar_common(void)
  42{
  43        u64 irqstat;
  44
  45        irqstat = read_sysreg_s(SYS_ICC_IAR1_EL1);
  46        dsb(sy);
  47        return irqstat;
  48}
  49
  50/*
  51 * Cavium ThunderX erratum 23154
  52 *
  53 * The gicv3 of ThunderX requires a modified version for reading the
  54 * IAR status to ensure data synchronization (access to icc_iar1_el1
  55 * is not sync'ed before and after).
  56 */
  57static inline u64 gic_read_iar_cavium_thunderx(void)
  58{
  59        u64 irqstat;
  60
  61        nops(8);
  62        irqstat = read_sysreg_s(SYS_ICC_IAR1_EL1);
  63        nops(4);
  64        mb();
  65
  66        return irqstat;
  67}
  68
  69static inline void gic_write_ctlr(u32 val)
  70{
  71        write_sysreg_s(val, SYS_ICC_CTLR_EL1);
  72        isb();
  73}
  74
  75static inline u32 gic_read_ctlr(void)
  76{
  77        return read_sysreg_s(SYS_ICC_CTLR_EL1);
  78}
  79
  80static inline void gic_write_grpen1(u32 val)
  81{
  82        write_sysreg_s(val, SYS_ICC_IGRPEN1_EL1);
  83        isb();
  84}
  85
  86static inline void gic_write_sgi1r(u64 val)
  87{
  88        write_sysreg_s(val, SYS_ICC_SGI1R_EL1);
  89}
  90
  91static inline u32 gic_read_sre(void)
  92{
  93        return read_sysreg_s(SYS_ICC_SRE_EL1);
  94}
  95
  96static inline void gic_write_sre(u32 val)
  97{
  98        write_sysreg_s(val, SYS_ICC_SRE_EL1);
  99        isb();
 100}
 101
 102static inline void gic_write_bpr1(u32 val)
 103{
 104        write_sysreg_s(val, SYS_ICC_BPR1_EL1);
 105}
 106
 107static inline u32 gic_read_pmr(void)
 108{
 109        return read_sysreg_s(SYS_ICC_PMR_EL1);
 110}
 111
 112static __always_inline void gic_write_pmr(u32 val)
 113{
 114        write_sysreg_s(val, SYS_ICC_PMR_EL1);
 115}
 116
 117static inline u32 gic_read_rpr(void)
 118{
 119        return read_sysreg_s(SYS_ICC_RPR_EL1);
 120}
 121
 122#define gic_read_typer(c)               readq_relaxed(c)
 123#define gic_write_irouter(v, c)         writeq_relaxed(v, c)
 124#define gic_read_lpir(c)                readq_relaxed(c)
 125#define gic_write_lpir(v, c)            writeq_relaxed(v, c)
 126
 127#define gic_flush_dcache_to_poc(a,l)    \
 128        dcache_clean_inval_poc((unsigned long)(a), (unsigned long)(a)+(l))
 129
 130#define gits_read_baser(c)              readq_relaxed(c)
 131#define gits_write_baser(v, c)          writeq_relaxed(v, c)
 132
 133#define gits_read_cbaser(c)             readq_relaxed(c)
 134#define gits_write_cbaser(v, c)         writeq_relaxed(v, c)
 135
 136#define gits_write_cwriter(v, c)        writeq_relaxed(v, c)
 137
 138#define gicr_read_propbaser(c)          readq_relaxed(c)
 139#define gicr_write_propbaser(v, c)      writeq_relaxed(v, c)
 140
 141#define gicr_write_pendbaser(v, c)      writeq_relaxed(v, c)
 142#define gicr_read_pendbaser(c)          readq_relaxed(c)
 143
 144#define gicr_write_vpropbaser(v, c)     writeq_relaxed(v, c)
 145#define gicr_read_vpropbaser(c)         readq_relaxed(c)
 146
 147#define gicr_write_vpendbaser(v, c)     writeq_relaxed(v, c)
 148#define gicr_read_vpendbaser(c)         readq_relaxed(c)
 149
 150static inline bool gic_prio_masking_enabled(void)
 151{
 152        return system_uses_irq_prio_masking();
 153}
 154
 155static inline void gic_pmr_mask_irqs(void)
 156{
 157        BUILD_BUG_ON(GICD_INT_DEF_PRI < (__GIC_PRIO_IRQOFF |
 158                                         GIC_PRIO_PSR_I_SET));
 159        BUILD_BUG_ON(GICD_INT_DEF_PRI >= GIC_PRIO_IRQON);
 160        /*
 161         * Need to make sure IRQON allows IRQs when SCR_EL3.FIQ is cleared
 162         * and non-secure PMR accesses are not subject to the shifts that
 163         * are applied to IRQ priorities
 164         */
 165        BUILD_BUG_ON((0x80 | (GICD_INT_DEF_PRI >> 1)) >= GIC_PRIO_IRQON);
 166        /*
 167         * Same situation as above, but now we make sure that we can mask
 168         * regular interrupts.
 169         */
 170        BUILD_BUG_ON((0x80 | (GICD_INT_DEF_PRI >> 1)) < (__GIC_PRIO_IRQOFF_NS |
 171                                                         GIC_PRIO_PSR_I_SET));
 172        gic_write_pmr(GIC_PRIO_IRQOFF);
 173}
 174
 175static inline void gic_arch_enable_irqs(void)
 176{
 177        asm volatile ("msr daifclr, #3" : : : "memory");
 178}
 179
 180#endif /* __ASSEMBLY__ */
 181#endif /* __ASM_ARCH_GICV3_H */
 182