Guest User

PoC for dropping priority in GIC

a guest
Mar 9th, 2018
122
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 3.88 KB | None | 0 0
  1.  arch/arm/include/asm/arch_gicv3.h   | 6 ++++++
  2.  arch/arm64/include/asm/arch_gicv3.h | 5 +++++
  3.  drivers/irqchip/irq-gic-v3.c        | 4 ++++
  4.  drivers/irqchip/irq-gic.c           | 5 +++++
  5.  include/linux/irqchip/arm-gic-v3.h  | 1 +
  6.  include/linux/irqchip/arm-gic.h     | 2 ++
  7.  6 files changed, 23 insertions(+)
  8.  
  9. diff --git a/arch/arm/include/asm/arch_gicv3.h b/arch/arm/include/asm/arch_gicv3.h
  10. index 1070044..06ea637 100644
  11. --- a/arch/arm/include/asm/arch_gicv3.h
  12. +++ b/arch/arm/include/asm/arch_gicv3.h
  13. @@ -34,6 +34,7 @@
  14.  #define ICC_SRE                __ACCESS_CP15(c12, 0, c12, 5)
  15.  #define ICC_IGRPEN1            __ACCESS_CP15(c12, 0, c12, 7)
  16.  #define ICC_BPR1           __ACCESS_CP15(c12, 0, c12, 3)
  17. +#define ICC_RPR                __ACCESS_CP15(c12, 0, c11, 3)
  18.  
  19.  #define ICC_HSRE           __ACCESS_CP15(c12, 4, c9, 5)
  20.  
  21. @@ -228,6 +229,11 @@ static inline void gic_write_bpr1(u32 val)
  22.     write_sysreg(val, ICC_BPR1);
  23.  }
  24.  
  25. +static inline u32 gic_read_rpr(void)
  26. +{
  27. +   return read_sysreg(ICC_RPR);
  28. +}
  29. +
  30.  /*
  31.   * Even in 32bit systems that use LPAE, there is no guarantee that the I/O
  32.   * interface provides true 64bit atomic accesses, so using strd/ldrd doesn't
  33. diff --git a/arch/arm64/include/asm/arch_gicv3.h b/arch/arm64/include/asm/arch_gicv3.h
  34. index 9becba9..18ab2c5 100644
  35. --- a/arch/arm64/include/asm/arch_gicv3.h
  36. +++ b/arch/arm64/include/asm/arch_gicv3.h
  37. @@ -119,6 +119,11 @@ static inline void gic_write_bpr1(u32 val)
  38.     write_sysreg_s(val, SYS_ICC_BPR1_EL1);
  39.  }
  40.  
  41. +static inline u32 gic_read_rpr(void)
  42. +{
  43. +   return read_sysreg_s(SYS_ICC_RPR_EL1);
  44. +}
  45. +
  46.  #define gic_read_typer(c)      readq_relaxed(c)
  47.  #define gic_write_irouter(v, c)        writeq_relaxed(v, c)
  48.  #define gic_read_lpir(c)       readq_relaxed(c)
  49. diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
  50. index d99cc07..602e5a1 100644
  51. --- a/drivers/irqchip/irq-gic-v3.c
  52. +++ b/drivers/irqchip/irq-gic-v3.c
  53. @@ -612,6 +612,10 @@ static void gic_cpu_init(void)
  54.  
  55.     gic_cpu_config(rbase, gic_redist_wait_for_rwp);
  56.  
  57. +   /* If the running priority isn't idle drop it */
  58. +   if (gic_read_rpr() != ICC_RPR_IDLE)
  59. +       gic_write_eoir(32);
  60. +
  61.     /* Give LPIs a spin */
  62.     if (IS_ENABLED(CONFIG_ARM_GIC_V3_ITS) && gic_dist_supports_lpis())
  63.         its_cpu_init();
  64. diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
  65. index 5e5877e..10eddcc 100644
  66. --- a/drivers/irqchip/irq-gic.c
  67. +++ b/drivers/irqchip/irq-gic.c
  68. @@ -532,6 +532,7 @@ static int gic_cpu_init(struct gic_chip_data *gic)
  69.  {
  70.     void __iomem *dist_base = gic_data_dist_base(gic);
  71.     void __iomem *base = gic_data_cpu_base(gic);
  72. +   void __iomem *cpu_base = gic_data_cpu_base(gic);
  73.     unsigned int cpu_mask, cpu = smp_processor_id();
  74.     int i;
  75.  
  76. @@ -562,6 +563,10 @@ static int gic_cpu_init(struct gic_chip_data *gic)
  77.  
  78.     gic_cpu_config(dist_base, NULL);
  79.  
  80. +   /* If the running priority isn't idle drop it */
  81. +   if (readl_relaxed(cpu_base + GIC_CPU_RUNNINGPRI) != GIC_CPU_IDLE_PRIORITY)
  82. +       writel_relaxed(32, cpu_base + GIC_CPU_EOI);
  83. +
  84.     writel_relaxed(GICC_INT_PRI_THRESHOLD, base + GIC_CPU_PRIMASK);
  85.     gic_cpu_if_up(gic);
  86.  
  87. diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
  88. index c00c4c33..1fce576 100644
  89. --- a/include/linux/irqchip/arm-gic-v3.h
  90. +++ b/include/linux/irqchip/arm-gic-v3.h
  91. @@ -476,6 +476,7 @@
  92.  #define ICC_SRE_EL1_DIB            (1U << 2)
  93.  #define ICC_SRE_EL1_DFB            (1U << 1)
  94.  #define ICC_SRE_EL1_SRE            (1U << 0)
  95. +#define ICC_RPR_IDLE           0xff
  96.  
  97.  /*
  98.   * Hypervisor interface registers (SRE only)
  99. diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h
  100. index d3453ee..df7edf6 100644
  101. --- a/include/linux/irqchip/arm-gic.h
  102. +++ b/include/linux/irqchip/arm-gic.h
  103. @@ -38,6 +38,8 @@
  104.  #define GIC_CPU_CTRL_EOImodeNS_SHIFT   9
  105.  #define GIC_CPU_CTRL_EOImodeNS     (1 << GIC_CPU_CTRL_EOImodeNS_SHIFT)
  106.  
  107. +#define GIC_CPU_IDLE_PRIORITY      0xff
  108. +
  109.  #define GICC_IAR_INT_ID_MASK       0x3ff
  110.  #define GICC_INT_SPURIOUS      1023
  111.  #define GICC_DIS_BYPASS_MASK       0x1e0
  112. --
  113. 2.7.4
Add Comment
Please, Sign In to add comment