Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v6.15 157 lines 3.1 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * ARM Generic Interrupt Controller (GIC) support 4 */ 5 6#include <errno.h> 7#include <linux/bits.h> 8#include <linux/sizes.h> 9 10#include "kvm_util.h" 11 12#include <gic.h> 13#include "gic_private.h" 14#include "processor.h" 15#include "spinlock.h" 16 17static const struct gic_common_ops *gic_common_ops; 18static struct spinlock gic_lock; 19 20static void gic_cpu_init(unsigned int cpu) 21{ 22 gic_common_ops->gic_cpu_init(cpu); 23} 24 25static void gic_dist_init(enum gic_type type, unsigned int nr_cpus) 26{ 27 const struct gic_common_ops *gic_ops = NULL; 28 29 spin_lock(&gic_lock); 30 31 /* Distributor initialization is needed only once per VM */ 32 if (gic_common_ops) { 33 spin_unlock(&gic_lock); 34 return; 35 } 36 37 if (type == GIC_V3) 38 gic_ops = &gicv3_ops; 39 40 GUEST_ASSERT(gic_ops); 41 42 gic_ops->gic_init(nr_cpus); 43 gic_common_ops = gic_ops; 44 45 /* Make sure that the initialized data is visible to all the vCPUs */ 46 dsb(sy); 47 48 spin_unlock(&gic_lock); 49} 50 51void gic_init(enum gic_type type, unsigned int nr_cpus) 52{ 53 uint32_t cpu = guest_get_vcpuid(); 54 55 GUEST_ASSERT(type < GIC_TYPE_MAX); 56 GUEST_ASSERT(nr_cpus); 57 58 gic_dist_init(type, nr_cpus); 59 gic_cpu_init(cpu); 60} 61 62void gic_irq_enable(unsigned int intid) 63{ 64 GUEST_ASSERT(gic_common_ops); 65 gic_common_ops->gic_irq_enable(intid); 66} 67 68void gic_irq_disable(unsigned int intid) 69{ 70 GUEST_ASSERT(gic_common_ops); 71 gic_common_ops->gic_irq_disable(intid); 72} 73 74unsigned int gic_get_and_ack_irq(void) 75{ 76 uint64_t irqstat; 77 unsigned int intid; 78 79 GUEST_ASSERT(gic_common_ops); 80 81 irqstat = gic_common_ops->gic_read_iar(); 82 intid = irqstat & GENMASK(23, 0); 83 84 return intid; 85} 86 87void gic_set_eoi(unsigned int intid) 88{ 89 GUEST_ASSERT(gic_common_ops); 90 gic_common_ops->gic_write_eoir(intid); 91} 92 93void gic_set_dir(unsigned int intid) 94{ 95 GUEST_ASSERT(gic_common_ops); 96 gic_common_ops->gic_write_dir(intid); 97} 98 99void gic_set_eoi_split(bool split) 100{ 101 GUEST_ASSERT(gic_common_ops); 102 gic_common_ops->gic_set_eoi_split(split); 103} 104 105void gic_set_priority_mask(uint64_t pmr) 106{ 107 GUEST_ASSERT(gic_common_ops); 108 gic_common_ops->gic_set_priority_mask(pmr); 109} 110 111void gic_set_priority(unsigned int intid, unsigned int prio) 112{ 113 GUEST_ASSERT(gic_common_ops); 114 gic_common_ops->gic_set_priority(intid, prio); 115} 116 117void gic_irq_set_active(unsigned int intid) 118{ 119 GUEST_ASSERT(gic_common_ops); 120 gic_common_ops->gic_irq_set_active(intid); 121} 122 123void gic_irq_clear_active(unsigned int intid) 124{ 125 GUEST_ASSERT(gic_common_ops); 126 gic_common_ops->gic_irq_clear_active(intid); 127} 128 129bool gic_irq_get_active(unsigned int intid) 130{ 131 GUEST_ASSERT(gic_common_ops); 132 return gic_common_ops->gic_irq_get_active(intid); 133} 134 135void gic_irq_set_pending(unsigned int intid) 136{ 137 GUEST_ASSERT(gic_common_ops); 138 gic_common_ops->gic_irq_set_pending(intid); 139} 140 141void gic_irq_clear_pending(unsigned int intid) 142{ 143 GUEST_ASSERT(gic_common_ops); 144 gic_common_ops->gic_irq_clear_pending(intid); 145} 146 147bool gic_irq_get_pending(unsigned int intid) 148{ 149 GUEST_ASSERT(gic_common_ops); 150 return gic_common_ops->gic_irq_get_pending(intid); 151} 152 153void gic_irq_set_config(unsigned int intid, bool is_edge) 154{ 155 GUEST_ASSERT(gic_common_ops); 156 gic_common_ops->gic_irq_set_config(intid, is_edge); 157}