1495e0022SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */ 29a489f45SDavid Vrabel /* 39a489f45SDavid Vrabel * Xen Event Channels (internal header) 49a489f45SDavid Vrabel * 59a489f45SDavid Vrabel * Copyright (C) 2013 Citrix Systems R&D Ltd. 69a489f45SDavid Vrabel */ 79a489f45SDavid Vrabel #ifndef __EVENTS_INTERNAL_H__ 89a489f45SDavid Vrabel #define __EVENTS_INTERNAL_H__ 99a489f45SDavid Vrabel 109a489f45SDavid Vrabel /* Interrupt types. */ 119a489f45SDavid Vrabel enum xen_irq_type { 129a489f45SDavid Vrabel IRQT_UNBOUND = 0, 139a489f45SDavid Vrabel IRQT_PIRQ, 149a489f45SDavid Vrabel IRQT_VIRQ, 159a489f45SDavid Vrabel IRQT_IPI, 169a489f45SDavid Vrabel IRQT_EVTCHN 179a489f45SDavid Vrabel }; 189a489f45SDavid Vrabel 199a489f45SDavid Vrabel /* 209a489f45SDavid Vrabel * Packed IRQ information: 219a489f45SDavid Vrabel * type - enum xen_irq_type 229a489f45SDavid Vrabel * event channel - irq->event channel mapping 239a489f45SDavid Vrabel * cpu - cpu this event channel is bound to 249a489f45SDavid Vrabel * index - type-specific information: 259a489f45SDavid Vrabel * PIRQ - vector, with MSB being "needs EIO", or physical IRQ of the HVM 269a489f45SDavid Vrabel * guest, or GSI (real passthrough IRQ) of the device. 279a489f45SDavid Vrabel * VIRQ - virq number 289a489f45SDavid Vrabel * IPI - IPI vector 299a489f45SDavid Vrabel * EVTCHN - 309a489f45SDavid Vrabel */ 319a489f45SDavid Vrabel struct irq_info { 329a489f45SDavid Vrabel struct list_head list; 33*e99502f7SJuergen Gross struct list_head eoi_list; 349a489f45SDavid Vrabel int refcnt; 359a489f45SDavid Vrabel enum xen_irq_type type; /* type */ 369a489f45SDavid Vrabel unsigned irq; 370102e4efSYan Yankovskyi evtchn_port_t evtchn; /* event channel */ 389a489f45SDavid Vrabel unsigned short cpu; /* cpu bound */ 39*e99502f7SJuergen Gross unsigned short eoi_cpu; /* EOI must happen on this cpu */ 40*e99502f7SJuergen Gross unsigned int irq_epoch; /* If eoi_cpu valid: irq_epoch of event */ 41*e99502f7SJuergen Gross u64 eoi_time; /* Time in jiffies when to EOI. */ 429a489f45SDavid Vrabel 439a489f45SDavid Vrabel union { 449a489f45SDavid Vrabel unsigned short virq; 459a489f45SDavid Vrabel enum ipi_vector ipi; 469a489f45SDavid Vrabel struct { 479a489f45SDavid Vrabel unsigned short pirq; 489a489f45SDavid Vrabel unsigned short gsi; 499a489f45SDavid Vrabel unsigned char vector; 509a489f45SDavid Vrabel unsigned char flags; 519a489f45SDavid Vrabel uint16_t domid; 529a489f45SDavid Vrabel } pirq; 539a489f45SDavid Vrabel } u; 549a489f45SDavid Vrabel }; 559a489f45SDavid Vrabel 569a489f45SDavid Vrabel #define PIRQ_NEEDS_EOI (1 << 0) 579a489f45SDavid Vrabel #define PIRQ_SHAREABLE (1 << 1) 584892c9b4SRoger Pau Monne #define PIRQ_MSI_GROUP (1 << 2) 599a489f45SDavid Vrabel 60*e99502f7SJuergen Gross struct evtchn_loop_ctrl; 61*e99502f7SJuergen Gross 62ab9a1ccaSDavid Vrabel struct evtchn_ops { 63d0b075ffSDavid Vrabel unsigned (*max_channels)(void); 64d0b075ffSDavid Vrabel unsigned (*nr_channels)(void); 65d0b075ffSDavid Vrabel 6608385875SDavid Vrabel int (*setup)(struct irq_info *info); 67ab9a1ccaSDavid Vrabel void (*bind_to_cpu)(struct irq_info *info, unsigned cpu); 68ab9a1ccaSDavid Vrabel 690102e4efSYan Yankovskyi void (*clear_pending)(evtchn_port_t port); 700102e4efSYan Yankovskyi void (*set_pending)(evtchn_port_t port); 710102e4efSYan Yankovskyi bool (*is_pending)(evtchn_port_t port); 720102e4efSYan Yankovskyi bool (*test_and_set_mask)(evtchn_port_t port); 730102e4efSYan Yankovskyi void (*mask)(evtchn_port_t port); 740102e4efSYan Yankovskyi void (*unmask)(evtchn_port_t port); 75ab9a1ccaSDavid Vrabel 76*e99502f7SJuergen Gross void (*handle_events)(unsigned cpu, struct evtchn_loop_ctrl *ctrl); 771fe56551SDavid Vrabel void (*resume)(void); 787beb290cSJuergen Gross 797beb290cSJuergen Gross int (*percpu_init)(unsigned int cpu); 807beb290cSJuergen Gross int (*percpu_deinit)(unsigned int cpu); 81ab9a1ccaSDavid Vrabel }; 82ab9a1ccaSDavid Vrabel 83ab9a1ccaSDavid Vrabel extern const struct evtchn_ops *evtchn_ops; 84ab9a1ccaSDavid Vrabel 85d0b075ffSDavid Vrabel extern int **evtchn_to_irq; 860102e4efSYan Yankovskyi int get_evtchn_to_irq(evtchn_port_t evtchn); 87*e99502f7SJuergen Gross void handle_irq_for_port(evtchn_port_t port, struct evtchn_loop_ctrl *ctrl); 889a489f45SDavid Vrabel 899a489f45SDavid Vrabel struct irq_info *info_for_irq(unsigned irq); 909a489f45SDavid Vrabel unsigned cpu_from_irq(unsigned irq); 910102e4efSYan Yankovskyi unsigned int cpu_from_evtchn(evtchn_port_t evtchn); 929a489f45SDavid Vrabel 93d0b075ffSDavid Vrabel static inline unsigned xen_evtchn_max_channels(void) 94d0b075ffSDavid Vrabel { 95d0b075ffSDavid Vrabel return evtchn_ops->max_channels(); 96d0b075ffSDavid Vrabel } 97d0b075ffSDavid Vrabel 9808385875SDavid Vrabel /* 9908385875SDavid Vrabel * Do any ABI specific setup for a bound event channel before it can 10008385875SDavid Vrabel * be unmasked and used. 10108385875SDavid Vrabel */ 10208385875SDavid Vrabel static inline int xen_evtchn_port_setup(struct irq_info *info) 10308385875SDavid Vrabel { 10408385875SDavid Vrabel if (evtchn_ops->setup) 10508385875SDavid Vrabel return evtchn_ops->setup(info); 10608385875SDavid Vrabel return 0; 10708385875SDavid Vrabel } 10808385875SDavid Vrabel 109ab9a1ccaSDavid Vrabel static inline void xen_evtchn_port_bind_to_cpu(struct irq_info *info, 110ab9a1ccaSDavid Vrabel unsigned cpu) 111ab9a1ccaSDavid Vrabel { 112ab9a1ccaSDavid Vrabel evtchn_ops->bind_to_cpu(info, cpu); 113ab9a1ccaSDavid Vrabel } 1149a489f45SDavid Vrabel 1150102e4efSYan Yankovskyi static inline void clear_evtchn(evtchn_port_t port) 116ab9a1ccaSDavid Vrabel { 117ab9a1ccaSDavid Vrabel evtchn_ops->clear_pending(port); 118ab9a1ccaSDavid Vrabel } 1199a489f45SDavid Vrabel 1200102e4efSYan Yankovskyi static inline void set_evtchn(evtchn_port_t port) 121ab9a1ccaSDavid Vrabel { 122ab9a1ccaSDavid Vrabel evtchn_ops->set_pending(port); 123ab9a1ccaSDavid Vrabel } 124ab9a1ccaSDavid Vrabel 1250102e4efSYan Yankovskyi static inline bool test_evtchn(evtchn_port_t port) 126ab9a1ccaSDavid Vrabel { 127ab9a1ccaSDavid Vrabel return evtchn_ops->is_pending(port); 128ab9a1ccaSDavid Vrabel } 129ab9a1ccaSDavid Vrabel 1300102e4efSYan Yankovskyi static inline bool test_and_set_mask(evtchn_port_t port) 131ab9a1ccaSDavid Vrabel { 132ab9a1ccaSDavid Vrabel return evtchn_ops->test_and_set_mask(port); 133ab9a1ccaSDavid Vrabel } 134ab9a1ccaSDavid Vrabel 1350102e4efSYan Yankovskyi static inline void mask_evtchn(evtchn_port_t port) 136ab9a1ccaSDavid Vrabel { 137ab9a1ccaSDavid Vrabel return evtchn_ops->mask(port); 138ab9a1ccaSDavid Vrabel } 139ab9a1ccaSDavid Vrabel 1400102e4efSYan Yankovskyi static inline void unmask_evtchn(evtchn_port_t port) 141ab9a1ccaSDavid Vrabel { 142ab9a1ccaSDavid Vrabel return evtchn_ops->unmask(port); 143ab9a1ccaSDavid Vrabel } 144ab9a1ccaSDavid Vrabel 145*e99502f7SJuergen Gross static inline void xen_evtchn_handle_events(unsigned cpu, 146*e99502f7SJuergen Gross struct evtchn_loop_ctrl *ctrl) 147ab9a1ccaSDavid Vrabel { 148*e99502f7SJuergen Gross return evtchn_ops->handle_events(cpu, ctrl); 149ab9a1ccaSDavid Vrabel } 150ab9a1ccaSDavid Vrabel 1511fe56551SDavid Vrabel static inline void xen_evtchn_resume(void) 1521fe56551SDavid Vrabel { 1531fe56551SDavid Vrabel if (evtchn_ops->resume) 1541fe56551SDavid Vrabel evtchn_ops->resume(); 1551fe56551SDavid Vrabel } 1561fe56551SDavid Vrabel 157ab9a1ccaSDavid Vrabel void xen_evtchn_2l_init(void); 1581fe56551SDavid Vrabel int xen_evtchn_fifo_init(void); 1599a489f45SDavid Vrabel 1609a489f45SDavid Vrabel #endif /* #ifndef __EVENTS_INTERNAL_H__ */ 161