qemu/include/hw/ppc/xics.h
<<
>>
Prefs
   1/*
   2 * QEMU PowerPC pSeries Logical Partition (aka sPAPR) hardware System Emulator
   3 *
   4 * PAPR Virtualized Interrupt System, aka ICS/ICP aka xics
   5 *
   6 * Copyright (c) 2010,2011 David Gibson, IBM Corporation.
   7 *
   8 * Permission is hereby granted, free of charge, to any person obtaining a copy
   9 * of this software and associated documentation files (the "Software"), to deal
  10 * in the Software without restriction, including without limitation the rights
  11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12 * copies of the Software, and to permit persons to whom the Software is
  13 * furnished to do so, subject to the following conditions:
  14 *
  15 * The above copyright notice and this permission notice shall be included in
  16 * all copies or substantial portions of the Software.
  17 *
  18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  24 * THE SOFTWARE.
  25 *
  26 */
  27
  28#ifndef XICS_H
  29#define XICS_H
  30
  31#include "hw/sysbus.h"
  32
  33#define TYPE_XICS_COMMON "xics-common"
  34#define XICS_COMMON(obj) OBJECT_CHECK(XICSState, (obj), TYPE_XICS_COMMON)
  35
  36/*
  37 * Retain xics as the type name to be compatible for migration. Rest all the
  38 * functions, class and variables are renamed as xics_spapr.
  39 */
  40#define TYPE_XICS_SPAPR "xics"
  41#define XICS_SPAPR(obj) OBJECT_CHECK(XICSState, (obj), TYPE_XICS_SPAPR)
  42
  43#define TYPE_XICS_SPAPR_KVM "xics-spapr-kvm"
  44#define XICS_SPAPR_KVM(obj) \
  45     OBJECT_CHECK(KVMXICSState, (obj), TYPE_XICS_SPAPR_KVM)
  46
  47#define XICS_COMMON_CLASS(klass) \
  48     OBJECT_CLASS_CHECK(XICSStateClass, (klass), TYPE_XICS_COMMON)
  49#define XICS_SPAPR_CLASS(klass) \
  50     OBJECT_CLASS_CHECK(XICSStateClass, (klass), TYPE_XICS_SPAPR)
  51#define XICS_COMMON_GET_CLASS(obj) \
  52     OBJECT_GET_CLASS(XICSStateClass, (obj), TYPE_XICS_COMMON)
  53#define XICS_SPAPR_GET_CLASS(obj) \
  54     OBJECT_GET_CLASS(XICSStateClass, (obj), TYPE_XICS_SPAPR)
  55
  56#define XICS_IPI        0x2
  57#define XICS_BUID       0x1
  58#define XICS_IRQ_BASE   (XICS_BUID << 12)
  59
  60/*
  61 * We currently only support one BUID which is our interrupt base
  62 * (the kernel implementation supports more but we don't exploit
  63 *  that yet)
  64 */
  65typedef struct XICSStateClass XICSStateClass;
  66typedef struct XICSState XICSState;
  67typedef struct ICPStateClass ICPStateClass;
  68typedef struct ICPState ICPState;
  69typedef struct ICSStateClass ICSStateClass;
  70typedef struct ICSState ICSState;
  71typedef struct ICSIRQState ICSIRQState;
  72
  73struct XICSStateClass {
  74    DeviceClass parent_class;
  75
  76    void (*cpu_setup)(XICSState *icp, PowerPCCPU *cpu);
  77    void (*set_nr_irqs)(XICSState *icp, uint32_t nr_irqs, Error **errp);
  78    void (*set_nr_servers)(XICSState *icp, uint32_t nr_servers, Error **errp);
  79};
  80
  81struct XICSState {
  82    /*< private >*/
  83    SysBusDevice parent_obj;
  84    /*< public >*/
  85    uint32_t nr_servers;
  86    uint32_t nr_irqs;
  87    ICPState *ss;
  88    QLIST_HEAD(, ICSState) ics;
  89};
  90
  91#define TYPE_ICP "icp"
  92#define ICP(obj) OBJECT_CHECK(ICPState, (obj), TYPE_ICP)
  93
  94#define TYPE_KVM_ICP "icp-kvm"
  95#define KVM_ICP(obj) OBJECT_CHECK(ICPState, (obj), TYPE_KVM_ICP)
  96
  97#define ICP_CLASS(klass) \
  98     OBJECT_CLASS_CHECK(ICPStateClass, (klass), TYPE_ICP)
  99#define ICP_GET_CLASS(obj) \
 100     OBJECT_GET_CLASS(ICPStateClass, (obj), TYPE_ICP)
 101
 102struct ICPStateClass {
 103    DeviceClass parent_class;
 104
 105    void (*pre_save)(ICPState *s);
 106    int (*post_load)(ICPState *s, int version_id);
 107};
 108
 109struct ICPState {
 110    /*< private >*/
 111    DeviceState parent_obj;
 112    /*< public >*/
 113    CPUState *cs;
 114    ICSState *xirr_owner;
 115    uint32_t xirr;
 116    uint8_t pending_priority;
 117    uint8_t mfrr;
 118    qemu_irq output;
 119    bool cap_irq_xics_enabled;
 120
 121    XICSState *xics;
 122};
 123
 124#define TYPE_ICS_BASE "ics-base"
 125#define ICS_BASE(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_BASE)
 126
 127/* Retain ics for sPAPR for migration from existing sPAPR guests */
 128#define TYPE_ICS_SIMPLE "ics"
 129#define ICS_SIMPLE(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_SIMPLE)
 130
 131#define TYPE_ICS_KVM "icskvm"
 132#define ICS_KVM(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_KVM)
 133
 134#define ICS_BASE_CLASS(klass) \
 135     OBJECT_CLASS_CHECK(ICSStateClass, (klass), TYPE_ICS_BASE)
 136#define ICS_BASE_GET_CLASS(obj) \
 137     OBJECT_GET_CLASS(ICSStateClass, (obj), TYPE_ICS_BASE)
 138
 139struct ICSStateClass {
 140    DeviceClass parent_class;
 141
 142    void (*pre_save)(ICSState *s);
 143    int (*post_load)(ICSState *s, int version_id);
 144    void (*reject)(ICSState *s, uint32_t irq);
 145    void (*resend)(ICSState *s);
 146    void (*eoi)(ICSState *s, uint32_t irq);
 147};
 148
 149struct ICSState {
 150    /*< private >*/
 151    DeviceState parent_obj;
 152    /*< public >*/
 153    uint32_t nr_irqs;
 154    uint32_t offset;
 155    qemu_irq *qirqs;
 156    ICSIRQState *irqs;
 157    XICSState *xics;
 158    QLIST_ENTRY(ICSState) list;
 159};
 160
 161static inline bool ics_valid_irq(ICSState *ics, uint32_t nr)
 162{
 163    return (ics->offset != 0) && (nr >= ics->offset)
 164        && (nr < (ics->offset + ics->nr_irqs));
 165}
 166
 167struct ICSIRQState {
 168    uint32_t server;
 169    uint8_t priority;
 170    uint8_t saved_priority;
 171#define XICS_STATUS_ASSERTED           0x1
 172#define XICS_STATUS_SENT               0x2
 173#define XICS_STATUS_REJECTED           0x4
 174#define XICS_STATUS_MASKED_PENDING     0x8
 175    uint8_t status;
 176/* (flags & XICS_FLAGS_IRQ_MASK) == 0 means the interrupt is not allocated */
 177#define XICS_FLAGS_IRQ_LSI             0x1
 178#define XICS_FLAGS_IRQ_MSI             0x2
 179#define XICS_FLAGS_IRQ_MASK            0x3
 180    uint8_t flags;
 181};
 182
 183#define XICS_IRQS_SPAPR               1024
 184
 185qemu_irq xics_get_qirq(XICSState *icp, int irq);
 186int xics_spapr_alloc(XICSState *icp, int irq_hint, bool lsi, Error **errp);
 187int xics_spapr_alloc_block(XICSState *icp, int num, bool lsi, bool align,
 188                           Error **errp);
 189void xics_spapr_free(XICSState *icp, int irq, int num);
 190void spapr_dt_xics(XICSState *xics, void *fdt, uint32_t phandle);
 191
 192void xics_cpu_setup(XICSState *icp, PowerPCCPU *cpu);
 193void xics_cpu_destroy(XICSState *icp, PowerPCCPU *cpu);
 194void xics_set_nr_servers(XICSState *xics, uint32_t nr_servers,
 195                         const char *typename, Error **errp);
 196
 197/* Internal XICS interfaces */
 198int xics_get_cpu_index_by_dt_id(int cpu_dt_id);
 199
 200void icp_set_cppr(ICPState *icp, uint8_t cppr);
 201void icp_set_mfrr(ICPState *icp, uint8_t mfrr);
 202uint32_t icp_accept(ICPState *ss);
 203uint32_t icp_ipoll(ICPState *ss, uint32_t *mfrr);
 204void icp_eoi(ICPState *icp, uint32_t xirr);
 205
 206void ics_simple_write_xive(ICSState *ics, int nr, int server,
 207                           uint8_t priority, uint8_t saved_priority);
 208
 209void ics_set_irq_type(ICSState *ics, int srcno, bool lsi);
 210
 211ICSState *xics_find_source(XICSState *icp, int irq);
 212
 213#endif /* XICS_H */
 214