18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright 2016,2017 IBM Corporation. 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci#ifndef _ASM_POWERPC_XIVE_H 68c2ecf20Sopenharmony_ci#define _ASM_POWERPC_XIVE_H 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <asm/opal-api.h> 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#define XIVE_INVALID_VP 0xffffffff 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#ifdef CONFIG_PPC_XIVE 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci/* 158c2ecf20Sopenharmony_ci * Thread Interrupt Management Area (TIMA) 168c2ecf20Sopenharmony_ci * 178c2ecf20Sopenharmony_ci * This is a global MMIO region divided in 4 pages of varying access 188c2ecf20Sopenharmony_ci * permissions, providing access to per-cpu interrupt management 198c2ecf20Sopenharmony_ci * functions. It always identifies the CPU doing the access based 208c2ecf20Sopenharmony_ci * on the PowerBus initiator ID, thus we always access via the 218c2ecf20Sopenharmony_ci * same offset regardless of where the code is executing 228c2ecf20Sopenharmony_ci */ 238c2ecf20Sopenharmony_ciextern void __iomem *xive_tima; 248c2ecf20Sopenharmony_ciextern unsigned long xive_tima_os; 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci/* 278c2ecf20Sopenharmony_ci * Offset in the TM area of our current execution level (provided by 288c2ecf20Sopenharmony_ci * the backend) 298c2ecf20Sopenharmony_ci */ 308c2ecf20Sopenharmony_ciextern u32 xive_tima_offset; 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci/* 338c2ecf20Sopenharmony_ci * Per-irq data (irq_get_handler_data for normal IRQs), IPIs 348c2ecf20Sopenharmony_ci * have it stored in the xive_cpu structure. We also cache 358c2ecf20Sopenharmony_ci * for normal interrupts the current target CPU. 368c2ecf20Sopenharmony_ci * 378c2ecf20Sopenharmony_ci * This structure is setup by the backend for each interrupt. 388c2ecf20Sopenharmony_ci */ 398c2ecf20Sopenharmony_cistruct xive_irq_data { 408c2ecf20Sopenharmony_ci u64 flags; 418c2ecf20Sopenharmony_ci u64 eoi_page; 428c2ecf20Sopenharmony_ci void __iomem *eoi_mmio; 438c2ecf20Sopenharmony_ci u64 trig_page; 448c2ecf20Sopenharmony_ci void __iomem *trig_mmio; 458c2ecf20Sopenharmony_ci u32 esb_shift; 468c2ecf20Sopenharmony_ci int src_chip; 478c2ecf20Sopenharmony_ci u32 hw_irq; 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci /* Setup/used by frontend */ 508c2ecf20Sopenharmony_ci int target; 518c2ecf20Sopenharmony_ci /* 528c2ecf20Sopenharmony_ci * saved_p means that there is a queue entry for this interrupt 538c2ecf20Sopenharmony_ci * in some CPU's queue (not including guest vcpu queues), even 548c2ecf20Sopenharmony_ci * if P is not set in the source ESB. 558c2ecf20Sopenharmony_ci * stale_p means that there is no queue entry for this interrupt 568c2ecf20Sopenharmony_ci * in some CPU's queue, even if P is set in the source ESB. 578c2ecf20Sopenharmony_ci */ 588c2ecf20Sopenharmony_ci bool saved_p; 598c2ecf20Sopenharmony_ci bool stale_p; 608c2ecf20Sopenharmony_ci}; 618c2ecf20Sopenharmony_ci#define XIVE_IRQ_FLAG_STORE_EOI 0x01 628c2ecf20Sopenharmony_ci#define XIVE_IRQ_FLAG_LSI 0x02 638c2ecf20Sopenharmony_ci#define XIVE_IRQ_FLAG_SHIFT_BUG 0x04 648c2ecf20Sopenharmony_ci#define XIVE_IRQ_FLAG_MASK_FW 0x08 658c2ecf20Sopenharmony_ci#define XIVE_IRQ_FLAG_EOI_FW 0x10 668c2ecf20Sopenharmony_ci#define XIVE_IRQ_FLAG_H_INT_ESB 0x20 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci/* Special flag set by KVM for excalation interrupts */ 698c2ecf20Sopenharmony_ci#define XIVE_IRQ_NO_EOI 0x80 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci#define XIVE_INVALID_CHIP_ID -1 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci/* A queue tracking structure in a CPU */ 748c2ecf20Sopenharmony_cistruct xive_q { 758c2ecf20Sopenharmony_ci __be32 *qpage; 768c2ecf20Sopenharmony_ci u32 msk; 778c2ecf20Sopenharmony_ci u32 idx; 788c2ecf20Sopenharmony_ci u32 toggle; 798c2ecf20Sopenharmony_ci u64 eoi_phys; 808c2ecf20Sopenharmony_ci u32 esc_irq; 818c2ecf20Sopenharmony_ci atomic_t count; 828c2ecf20Sopenharmony_ci atomic_t pending_count; 838c2ecf20Sopenharmony_ci u64 guest_qaddr; 848c2ecf20Sopenharmony_ci u32 guest_qshift; 858c2ecf20Sopenharmony_ci}; 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci/* Global enable flags for the XIVE support */ 888c2ecf20Sopenharmony_ciextern bool __xive_enabled; 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_cistatic inline bool xive_enabled(void) { return __xive_enabled; } 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_cibool xive_spapr_init(void); 938c2ecf20Sopenharmony_cibool xive_native_init(void); 948c2ecf20Sopenharmony_civoid xive_smp_probe(void); 958c2ecf20Sopenharmony_ciint xive_smp_prepare_cpu(unsigned int cpu); 968c2ecf20Sopenharmony_civoid xive_smp_setup_cpu(void); 978c2ecf20Sopenharmony_civoid xive_smp_disable_cpu(void); 988c2ecf20Sopenharmony_civoid xive_teardown_cpu(void); 998c2ecf20Sopenharmony_civoid xive_shutdown(void); 1008c2ecf20Sopenharmony_civoid xive_flush_interrupt(void); 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci/* xmon hook */ 1038c2ecf20Sopenharmony_civoid xmon_xive_do_dump(int cpu); 1048c2ecf20Sopenharmony_ciint xmon_xive_get_irq_config(u32 hw_irq, struct irq_data *d); 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci/* APIs used by KVM */ 1078c2ecf20Sopenharmony_ciu32 xive_native_default_eq_shift(void); 1088c2ecf20Sopenharmony_ciu32 xive_native_alloc_vp_block(u32 max_vcpus); 1098c2ecf20Sopenharmony_civoid xive_native_free_vp_block(u32 vp_base); 1108c2ecf20Sopenharmony_ciint xive_native_populate_irq_data(u32 hw_irq, 1118c2ecf20Sopenharmony_ci struct xive_irq_data *data); 1128c2ecf20Sopenharmony_civoid xive_cleanup_irq_data(struct xive_irq_data *xd); 1138c2ecf20Sopenharmony_civoid xive_native_free_irq(u32 irq); 1148c2ecf20Sopenharmony_ciint xive_native_configure_irq(u32 hw_irq, u32 target, u8 prio, u32 sw_irq); 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_ciint xive_native_configure_queue(u32 vp_id, struct xive_q *q, u8 prio, 1178c2ecf20Sopenharmony_ci __be32 *qpage, u32 order, bool can_escalate); 1188c2ecf20Sopenharmony_civoid xive_native_disable_queue(u32 vp_id, struct xive_q *q, u8 prio); 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_civoid xive_native_sync_source(u32 hw_irq); 1218c2ecf20Sopenharmony_civoid xive_native_sync_queue(u32 hw_irq); 1228c2ecf20Sopenharmony_cibool is_xive_irq(struct irq_chip *chip); 1238c2ecf20Sopenharmony_ciint xive_native_enable_vp(u32 vp_id, bool single_escalation); 1248c2ecf20Sopenharmony_ciint xive_native_disable_vp(u32 vp_id); 1258c2ecf20Sopenharmony_ciint xive_native_get_vp_info(u32 vp_id, u32 *out_cam_id, u32 *out_chip_id); 1268c2ecf20Sopenharmony_cibool xive_native_has_single_escalation(void); 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ciint xive_native_get_queue_info(u32 vp_id, uint32_t prio, 1298c2ecf20Sopenharmony_ci u64 *out_qpage, 1308c2ecf20Sopenharmony_ci u64 *out_qsize, 1318c2ecf20Sopenharmony_ci u64 *out_qeoi_page, 1328c2ecf20Sopenharmony_ci u32 *out_escalate_irq, 1338c2ecf20Sopenharmony_ci u64 *out_qflags); 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ciint xive_native_get_queue_state(u32 vp_id, uint32_t prio, u32 *qtoggle, 1368c2ecf20Sopenharmony_ci u32 *qindex); 1378c2ecf20Sopenharmony_ciint xive_native_set_queue_state(u32 vp_id, uint32_t prio, u32 qtoggle, 1388c2ecf20Sopenharmony_ci u32 qindex); 1398c2ecf20Sopenharmony_ciint xive_native_get_vp_state(u32 vp_id, u64 *out_state); 1408c2ecf20Sopenharmony_cibool xive_native_has_queue_state_support(void); 1418c2ecf20Sopenharmony_ciextern u32 xive_native_alloc_irq_on_chip(u32 chip_id); 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_cistatic inline u32 xive_native_alloc_irq(void) 1448c2ecf20Sopenharmony_ci{ 1458c2ecf20Sopenharmony_ci return xive_native_alloc_irq_on_chip(OPAL_XIVE_ANY_CHIP); 1468c2ecf20Sopenharmony_ci} 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci#else 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_cistatic inline bool xive_enabled(void) { return false; } 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_cistatic inline bool xive_spapr_init(void) { return false; } 1538c2ecf20Sopenharmony_cistatic inline bool xive_native_init(void) { return false; } 1548c2ecf20Sopenharmony_cistatic inline void xive_smp_probe(void) { } 1558c2ecf20Sopenharmony_cistatic inline int xive_smp_prepare_cpu(unsigned int cpu) { return -EINVAL; } 1568c2ecf20Sopenharmony_cistatic inline void xive_smp_setup_cpu(void) { } 1578c2ecf20Sopenharmony_cistatic inline void xive_smp_disable_cpu(void) { } 1588c2ecf20Sopenharmony_cistatic inline void xive_shutdown(void) { } 1598c2ecf20Sopenharmony_cistatic inline void xive_flush_interrupt(void) { } 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_cistatic inline u32 xive_native_alloc_vp_block(u32 max_vcpus) { return XIVE_INVALID_VP; } 1628c2ecf20Sopenharmony_cistatic inline void xive_native_free_vp_block(u32 vp_base) { } 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_ci#endif 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci#endif /* _ASM_POWERPC_XIVE_H */ 167