13d0407baSopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
23d0407baSopenharmony_ci/*
33d0407baSopenharmony_ci * Copyright (C) 2016,2017 ARM Limited, All Rights Reserved.
43d0407baSopenharmony_ci * Author: Marc Zyngier <marc.zyngier@arm.com>
53d0407baSopenharmony_ci */
63d0407baSopenharmony_ci
73d0407baSopenharmony_ci#ifndef __LINUX_IRQCHIP_ARM_GIC_V4_H
83d0407baSopenharmony_ci#define __LINUX_IRQCHIP_ARM_GIC_V4_H
93d0407baSopenharmony_ci
103d0407baSopenharmony_cistruct its_vpe;
113d0407baSopenharmony_ci
123d0407baSopenharmony_ci/*
133d0407baSopenharmony_ci * Maximum number of ITTs when GITS_TYPER.VMOVP == 0, using the
143d0407baSopenharmony_ci * ITSList mechanism to perform inter-ITS synchronization.
153d0407baSopenharmony_ci */
163d0407baSopenharmony_ci#define GICv4_ITS_LIST_MAX 16
173d0407baSopenharmony_ci
183d0407baSopenharmony_ci/* Embedded in kvm.arch */
193d0407baSopenharmony_cistruct its_vm {
203d0407baSopenharmony_ci    struct fwnode_handle *fwnode;
213d0407baSopenharmony_ci    struct irq_domain *domain;
223d0407baSopenharmony_ci    struct page *vprop_page;
233d0407baSopenharmony_ci    struct its_vpe **vpes;
243d0407baSopenharmony_ci    int nr_vpes;
253d0407baSopenharmony_ci    irq_hw_number_t db_lpi_base;
263d0407baSopenharmony_ci    unsigned long *db_bitmap;
273d0407baSopenharmony_ci    int nr_db_lpis;
283d0407baSopenharmony_ci    u32 vlpi_count[GICv4_ITS_LIST_MAX];
293d0407baSopenharmony_ci};
303d0407baSopenharmony_ci
313d0407baSopenharmony_ci/* Embedded in kvm_vcpu.arch */
323d0407baSopenharmony_cistruct its_vpe {
333d0407baSopenharmony_ci    struct page *vpt_page;
343d0407baSopenharmony_ci    struct its_vm *its_vm;
353d0407baSopenharmony_ci    /* per-vPE VLPI tracking */
363d0407baSopenharmony_ci    atomic_t vlpi_count;
373d0407baSopenharmony_ci    /* Doorbell interrupt */
383d0407baSopenharmony_ci    int irq;
393d0407baSopenharmony_ci    irq_hw_number_t vpe_db_lpi;
403d0407baSopenharmony_ci    /* VPE resident */
413d0407baSopenharmony_ci    bool resident;
423d0407baSopenharmony_ci    /* VPT parse complete */
433d0407baSopenharmony_ci    bool ready;
443d0407baSopenharmony_ci    union {
453d0407baSopenharmony_ci        /* GICv4.0 implementations */
463d0407baSopenharmony_ci        struct {
473d0407baSopenharmony_ci            /* VPE proxy mapping */
483d0407baSopenharmony_ci            int vpe_proxy_event;
493d0407baSopenharmony_ci            /* Implementation Defined Area Invalid */
503d0407baSopenharmony_ci            bool idai;
513d0407baSopenharmony_ci        };
523d0407baSopenharmony_ci        /* GICv4.1 implementations */
533d0407baSopenharmony_ci        struct {
543d0407baSopenharmony_ci            struct fwnode_handle *fwnode;
553d0407baSopenharmony_ci            struct irq_domain *sgi_domain;
563d0407baSopenharmony_ci            struct {
573d0407baSopenharmony_ci                u8 priority;
583d0407baSopenharmony_ci                bool enabled;
593d0407baSopenharmony_ci                bool group;
603d0407baSopenharmony_ci            } sgi_config[16];
613d0407baSopenharmony_ci            atomic_t vmapp_count;
623d0407baSopenharmony_ci        };
633d0407baSopenharmony_ci    };
643d0407baSopenharmony_ci
653d0407baSopenharmony_ci    /*
663d0407baSopenharmony_ci     * Ensures mutual exclusion between affinity setting of the
673d0407baSopenharmony_ci     * vPE and vLPI operations using vpe->col_idx.
683d0407baSopenharmony_ci     */
693d0407baSopenharmony_ci    raw_spinlock_t vpe_lock;
703d0407baSopenharmony_ci    /*
713d0407baSopenharmony_ci     * This collection ID is used to indirect the target
723d0407baSopenharmony_ci     * redistributor for this VPE. The ID itself isn't involved in
733d0407baSopenharmony_ci     * programming of the ITS.
743d0407baSopenharmony_ci     */
753d0407baSopenharmony_ci    u16 col_idx;
763d0407baSopenharmony_ci    /* Unique (system-wide) VPE identifier */
773d0407baSopenharmony_ci    u16 vpe_id;
783d0407baSopenharmony_ci    /* Pending VLPIs on schedule out? */
793d0407baSopenharmony_ci    bool pending_last;
803d0407baSopenharmony_ci};
813d0407baSopenharmony_ci
823d0407baSopenharmony_ci/*
833d0407baSopenharmony_ci * struct its_vlpi_map: structure describing the mapping of a
843d0407baSopenharmony_ci * VLPI. Only to be interpreted in the context of a physical interrupt
853d0407baSopenharmony_ci * it complements.  To be used as the vcpu_info passed to
863d0407baSopenharmony_ci * irq_set_vcpu_affinity().
873d0407baSopenharmony_ci *
883d0407baSopenharmony_ci * @vm:        Pointer to the GICv4 notion of a VM
893d0407baSopenharmony_ci * @vpe:    Pointer to the GICv4 notion of a virtual CPU (VPE)
903d0407baSopenharmony_ci * @vintid:    Virtual LPI number
913d0407baSopenharmony_ci * @properties:    Priority and enable bits (as written in the prop table)
923d0407baSopenharmony_ci * @db_enabled:    Is the VPE doorbell to be generated?
933d0407baSopenharmony_ci */
943d0407baSopenharmony_cistruct its_vlpi_map {
953d0407baSopenharmony_ci    struct its_vm *vm;
963d0407baSopenharmony_ci    struct its_vpe *vpe;
973d0407baSopenharmony_ci    u32 vintid;
983d0407baSopenharmony_ci    u8 properties;
993d0407baSopenharmony_ci    bool db_enabled;
1003d0407baSopenharmony_ci};
1013d0407baSopenharmony_ci
1023d0407baSopenharmony_cienum its_vcpu_info_cmd_type {
1033d0407baSopenharmony_ci    MAP_VLPI,
1043d0407baSopenharmony_ci    GET_VLPI,
1053d0407baSopenharmony_ci    PROP_UPDATE_VLPI,
1063d0407baSopenharmony_ci    PROP_UPDATE_AND_INV_VLPI,
1073d0407baSopenharmony_ci    SCHEDULE_VPE,
1083d0407baSopenharmony_ci    DESCHEDULE_VPE,
1093d0407baSopenharmony_ci    COMMIT_VPE,
1103d0407baSopenharmony_ci    INVALL_VPE,
1113d0407baSopenharmony_ci    PROP_UPDATE_VSGI,
1123d0407baSopenharmony_ci};
1133d0407baSopenharmony_ci
1143d0407baSopenharmony_cistruct its_cmd_info {
1153d0407baSopenharmony_ci    enum its_vcpu_info_cmd_type cmd_type;
1163d0407baSopenharmony_ci    union {
1173d0407baSopenharmony_ci        struct its_vlpi_map *map;
1183d0407baSopenharmony_ci        u8 config;
1193d0407baSopenharmony_ci        bool req_db;
1203d0407baSopenharmony_ci        struct {
1213d0407baSopenharmony_ci            bool g0en;
1223d0407baSopenharmony_ci            bool g1en;
1233d0407baSopenharmony_ci        };
1243d0407baSopenharmony_ci        struct {
1253d0407baSopenharmony_ci            u8 priority;
1263d0407baSopenharmony_ci            bool group;
1273d0407baSopenharmony_ci        };
1283d0407baSopenharmony_ci    };
1293d0407baSopenharmony_ci};
1303d0407baSopenharmony_ci
1313d0407baSopenharmony_ciint its_alloc_vcpu_irqs(struct its_vm *vm);
1323d0407baSopenharmony_civoid its_free_vcpu_irqs(struct its_vm *vm);
1333d0407baSopenharmony_ciint its_make_vpe_resident(struct its_vpe *vpe, bool g0en, bool g1en);
1343d0407baSopenharmony_ciint its_make_vpe_non_resident(struct its_vpe *vpe, bool db);
1353d0407baSopenharmony_ciint its_commit_vpe(struct its_vpe *vpe);
1363d0407baSopenharmony_ciint its_invall_vpe(struct its_vpe *vpe);
1373d0407baSopenharmony_ciint its_map_vlpi(int irq, struct its_vlpi_map *map);
1383d0407baSopenharmony_ciint its_get_vlpi(int irq, struct its_vlpi_map *map);
1393d0407baSopenharmony_ciint its_unmap_vlpi(int irq);
1403d0407baSopenharmony_ciint its_prop_update_vlpi(int irq, u8 config, bool inv);
1413d0407baSopenharmony_ciint its_prop_update_vsgi(int irq, u8 priority, bool group);
1423d0407baSopenharmony_ci
1433d0407baSopenharmony_cistruct irq_domain_ops;
1443d0407baSopenharmony_ciint its_init_v4(struct irq_domain *domain, const struct irq_domain_ops *vpe_ops, const struct irq_domain_ops *sgi_ops);
1453d0407baSopenharmony_ci
1463d0407baSopenharmony_ci#endif
147