xive.h 16.0 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
/*
 * QEMU PowerPC XIVE interrupt controller model
 *
 *
 * The POWER9 processor comes with a new interrupt controller, called
 * XIVE as "eXternal Interrupt Virtualization Engine".
 *
 * = Overall architecture
 *
 *
 *              XIVE Interrupt Controller
 *              +------------------------------------+      IPIs
 *              | +---------+ +---------+ +--------+ |    +-------+
 *              | |VC       | |CQ       | |PC      |----> | CORES |
 *              | |     esb | |         | |        |----> |       |
 *              | |     eas | |  Bridge | |   tctx |----> |       |
 *              | |SC   end | |         | |    nvt | |    |       |
 *  +------+    | +---------+ +----+----+ +--------+ |    +-+-+-+-+
 *  | RAM  |    +------------------|-----------------+      | | |
 *  |      |                       |                        | | |
 *  |      |                       |                        | | |
 *  |      |  +--------------------v------------------------v-v-v--+    other
 *  |      <--+                     Power Bus                      +--> chips
 *  |  esb |  +---------+-----------------------+------------------+
 *  |  eas |            |                       |
 *  |  end |         +--|------+                |
 *  |  nvt |       +----+----+ |           +----+----+
 *  +------+       |SC       | |           |SC       |
 *                 |         | |           |         |
 *                 | PQ-bits | |           | PQ-bits |
 *                 | local   |-+           |  in VC  |
 *                 +---------+             +---------+
 *                    PCIe                 NX,NPU,CAPI
 *
 *                   SC: Source Controller (aka. IVSE)
 *                   VC: Virtualization Controller (aka. IVRE)
 *                   PC: Presentation Controller (aka. IVPE)
 *                   CQ: Common Queue (Bridge)
 *
 *              PQ-bits: 2 bits source state machine (P:pending Q:queued)
 *                  esb: Event State Buffer (Array of PQ bits in an IVSE)
 *                  eas: Event Assignment Structure
 *                  end: Event Notification Descriptor
 *                  nvt: Notification Virtual Target
 *                 tctx: Thread interrupt Context
 *
 *
 * The XIVE IC is composed of three sub-engines :
 *
 * - Interrupt Virtualization Source Engine (IVSE), or Source
 *   Controller (SC). These are found in PCI PHBs, in the PSI host
 *   bridge controller, but also inside the main controller for the
 *   core IPIs and other sub-chips (NX, CAP, NPU) of the
 *   chip/processor. They are configured to feed the IVRE with events.
 *
 * - Interrupt Virtualization Routing Engine (IVRE) or Virtualization
 *   Controller (VC). Its job is to match an event source with an
 *   Event Notification Descriptor (END).
 *
 * - Interrupt Virtualization Presentation Engine (IVPE) or
 *   Presentation Controller (PC). It maintains the interrupt context
 *   state of each thread and handles the delivery of the external
 *   exception to the thread.
 *
 * In XIVE 1.0, the sub-engines used to be referred as:
 *
 *   SC     Source Controller
 *   VC     Virtualization Controller
 *   PC     Presentation Controller
 *   CQ     Common Queue (PowerBUS Bridge)
 *
 *
 * = XIVE internal tables
 *
 * Each of the sub-engines uses a set of tables to redirect exceptions
 * from event sources to CPU threads.
 *
 *                                           +-------+
 *   User or OS                              |  EQ   |
 *       or                          +------>|entries|
 *   Hypervisor                      |       |  ..   |
 *     Memory                        |       +-------+
 *                                   |           ^
 *                                   |           |
 *              +-------------------------------------------------+
 *                                   |           |
 *   Hypervisor      +------+    +---+--+    +---+--+   +------+
 *     Memory        | ESB  |    | EAT  |    | ENDT |   | NVTT |
 *    (skiboot)      +----+-+    +----+-+    +----+-+   +------+
 *                     ^  |        ^  |        ^  |       ^
 *                     |  |        |  |        |  |       |
 *              +-------------------------------------------------+
 *                     |  |        |  |        |  |       |
 *                     |  |        |  |        |  |       |
 *                +----|--|--------|--|--------|--|-+   +-|-----+    +------+
 *                |    |  |        |  |        |  | |   | | tctx|    |Thread|
 *   IPI or   --> |    +  v        +  v        +  v |---| +  .. |----->     |
 *  HW events --> |                                 |   |       |    |      |
 *    IVSE        |             IVRE                |   | IVPE  |    +------+
 *                +---------------------------------+   +-------+
 *
 *
 *
 * The IVSE have a 2-bits state machine, P for pending and Q for queued,
 * for each source that allows events to be triggered. They are stored in
 * an Event State Buffer (ESB) array and can be controlled by MMIOs.
 *
 * If the event is let through, the IVRE looks up in the Event Assignment
 * Structure (EAS) table for an Event Notification Descriptor (END)
 * configured for the source. Each Event Notification Descriptor defines
 * a notification path to a CPU and an in-memory Event Queue, in which
 * will be enqueued an EQ data for the OS to pull.
 *
 * The IVPE determines if a Notification Virtual Target (NVT) can
 * handle the event by scanning the thread contexts of the VCPUs
 * dispatched on the processor HW threads. It maintains the state of
 * the thread interrupt context (TCTX) of each thread in a NVT table.
 *
 * = Acronyms
 *
 *          Description                     In XIVE 1.0, used to be referred as
 *
 *   EAS    Event Assignment Structure      IVE   Interrupt Virt. Entry
 *   EAT    Event Assignment Table          IVT   Interrupt Virt. Table
 *   ENDT   Event Notif. Descriptor Table   EQDT  Event Queue Desc. Table
 *   EQ     Event Queue                     same
 *   ESB    Event State Buffer              SBE   State Bit Entry
 *   NVT    Notif. Virtual Target           VPD   Virtual Processor Desc.
 *   NVTT   Notif. Virtual Target Table     VPDT  Virtual Processor Desc. Table
 *   TCTX   Thread interrupt Context
 *
 *
 * Copyright (c) 2017-2018, IBM Corporation.
 *
 * This code is licensed under the GPL version 2 or later. See the
 * COPYING file in the top-level directory.
 *
 */

#ifndef PPC_XIVE_H
#define PPC_XIVE_H

C
Cédric Le Goater 已提交
143
#include "sysemu/kvm.h"
144
#include "hw/qdev-core.h"
145 146
#include "hw/sysbus.h"
#include "hw/ppc/xive_regs.h"
147

148
/*
149
 * XIVE Notifier (Interface between Source and Router)
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
 */

typedef struct XiveNotifier {
    Object parent;
} XiveNotifier;

#define TYPE_XIVE_NOTIFIER "xive-notifier"
#define XIVE_NOTIFIER(obj)                                     \
    OBJECT_CHECK(XiveNotifier, (obj), TYPE_XIVE_NOTIFIER)
#define XIVE_NOTIFIER_CLASS(klass)                                     \
    OBJECT_CLASS_CHECK(XiveNotifierClass, (klass), TYPE_XIVE_NOTIFIER)
#define XIVE_NOTIFIER_GET_CLASS(obj)                                   \
    OBJECT_GET_CLASS(XiveNotifierClass, (obj), TYPE_XIVE_NOTIFIER)

typedef struct XiveNotifierClass {
    InterfaceClass parent;
    void (*notify)(XiveNotifier *xn, uint32_t lisn);
} XiveNotifierClass;

169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
/*
 * XIVE Interrupt Source
 */

#define TYPE_XIVE_SOURCE "xive-source"
#define XIVE_SOURCE(obj) OBJECT_CHECK(XiveSource, (obj), TYPE_XIVE_SOURCE)

/*
 * XIVE Interrupt Source characteristics, which define how the ESB are
 * controlled.
 */
#define XIVE_SRC_H_INT_ESB     0x1 /* ESB managed with hcall H_INT_ESB */
#define XIVE_SRC_STORE_EOI     0x2 /* Store EOI supported */

typedef struct XiveSource {
    DeviceState parent;

    /* IRQs */
    uint32_t        nr_irqs;
188
    unsigned long   *lsi_map;
189

190
    /* PQ bits and LSI assertion bit */
191 192 193 194 195 196
    uint8_t         *status;

    /* ESB memory region */
    uint64_t        esb_flags;
    uint32_t        esb_shift;
    MemoryRegion    esb_mmio;
197

C
Cédric Le Goater 已提交
198 199
    /* KVM support */
    void            *esb_mmap;
200
    MemoryRegion    esb_mmio_kvm;
C
Cédric Le Goater 已提交
201

202
    XiveNotifier    *xive;
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251
} XiveSource;

/*
 * ESB MMIO setting. Can be one page, for both source triggering and
 * source management, or two different pages. See below for magic
 * values.
 */
#define XIVE_ESB_4K          12 /* PSI HB only */
#define XIVE_ESB_4K_2PAGE    13
#define XIVE_ESB_64K         16
#define XIVE_ESB_64K_2PAGE   17

static inline bool xive_source_esb_has_2page(XiveSource *xsrc)
{
    return xsrc->esb_shift == XIVE_ESB_64K_2PAGE ||
        xsrc->esb_shift == XIVE_ESB_4K_2PAGE;
}

/* The trigger page is always the first/even page */
static inline hwaddr xive_source_esb_page(XiveSource *xsrc, uint32_t srcno)
{
    assert(srcno < xsrc->nr_irqs);
    return (1ull << xsrc->esb_shift) * srcno;
}

/* In a two pages ESB MMIO setting, the odd page is for management */
static inline hwaddr xive_source_esb_mgmt(XiveSource *xsrc, int srcno)
{
    hwaddr addr = xive_source_esb_page(xsrc, srcno);

    if (xive_source_esb_has_2page(xsrc)) {
        addr += (1 << (xsrc->esb_shift - 1));
    }

    return addr;
}

/*
 * Each interrupt source has a 2-bit state machine which can be
 * controlled by MMIO. P indicates that an interrupt is pending (has
 * been sent to a queue and is waiting for an EOI). Q indicates that
 * the interrupt has been triggered while pending.
 *
 * This acts as a coalescing mechanism in order to guarantee that a
 * given interrupt only occurs at most once in a queue.
 *
 * When doing an EOI, the Q bit will indicate if the interrupt
 * needs to be re-triggered.
 */
252
#define XIVE_STATUS_ASSERTED  0x4  /* Extra bit for LSI */
253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284
#define XIVE_ESB_VAL_P        0x2
#define XIVE_ESB_VAL_Q        0x1

#define XIVE_ESB_RESET        0x0
#define XIVE_ESB_PENDING      XIVE_ESB_VAL_P
#define XIVE_ESB_QUEUED       (XIVE_ESB_VAL_P | XIVE_ESB_VAL_Q)
#define XIVE_ESB_OFF          XIVE_ESB_VAL_Q

/*
 * "magic" Event State Buffer (ESB) MMIO offsets.
 *
 * The following offsets into the ESB MMIO allow to read or manipulate
 * the PQ bits. They must be used with an 8-byte load instruction.
 * They all return the previous state of the interrupt (atomically).
 *
 * Additionally, some ESB pages support doing an EOI via a store and
 * some ESBs support doing a trigger via a separate trigger page.
 */
#define XIVE_ESB_STORE_EOI      0x400 /* Store */
#define XIVE_ESB_LOAD_EOI       0x000 /* Load */
#define XIVE_ESB_GET            0x800 /* Load */
#define XIVE_ESB_SET_PQ_00      0xc00 /* Load */
#define XIVE_ESB_SET_PQ_01      0xd00 /* Load */
#define XIVE_ESB_SET_PQ_10      0xe00 /* Load */
#define XIVE_ESB_SET_PQ_11      0xf00 /* Load */

uint8_t xive_source_esb_get(XiveSource *xsrc, uint32_t srcno);
uint8_t xive_source_esb_set(XiveSource *xsrc, uint32_t srcno, uint8_t pq);

void xive_source_pic_print_info(XiveSource *xsrc, uint32_t offset,
                                Monitor *mon);

285 286 287 288 289 290
static inline bool xive_source_irq_is_lsi(XiveSource *xsrc, uint32_t srcno)
{
    assert(srcno < xsrc->nr_irqs);
    return test_bit(srcno, xsrc->lsi_map);
}

G
Greg Kurz 已提交
291
static inline void xive_source_irq_set_lsi(XiveSource *xsrc, uint32_t srcno)
292 293
{
    assert(srcno < xsrc->nr_irqs);
G
Greg Kurz 已提交
294
    bitmap_set(xsrc->lsi_map, srcno, 1);
295 296
}

297 298
void xive_source_set_irq(void *opaque, int srcno, int val);

299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320
/*
 * XIVE Thread interrupt Management (TM) context
 */

#define TYPE_XIVE_TCTX "xive-tctx"
#define XIVE_TCTX(obj) OBJECT_CHECK(XiveTCTX, (obj), TYPE_XIVE_TCTX)

/*
 * XIVE Thread interrupt Management register rings :
 *
 *   QW-0  User       event-based exception state
 *   QW-1  O/S        OS context for priority management, interrupt acks
 *   QW-2  Pool       hypervisor pool context for virtual processors dispatched
 *   QW-3  Physical   physical thread context and security context
 */
#define XIVE_TM_RING_COUNT      4
#define XIVE_TM_RING_SIZE       0x10

typedef struct XiveTCTX {
    DeviceState parent_obj;

    CPUState    *cs;
321 322
    qemu_irq    hv_output;
    qemu_irq    os_output;
323 324 325 326

    uint8_t     regs[XIVE_TM_RING_COUNT * XIVE_TM_RING_SIZE];
} XiveTCTX;

327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348
/*
 * XIVE Router
 */

typedef struct XiveRouter {
    SysBusDevice    parent;
} XiveRouter;

#define TYPE_XIVE_ROUTER "xive-router"
#define XIVE_ROUTER(obj)                                \
    OBJECT_CHECK(XiveRouter, (obj), TYPE_XIVE_ROUTER)
#define XIVE_ROUTER_CLASS(klass)                                        \
    OBJECT_CLASS_CHECK(XiveRouterClass, (klass), TYPE_XIVE_ROUTER)
#define XIVE_ROUTER_GET_CLASS(obj)                              \
    OBJECT_GET_CLASS(XiveRouterClass, (obj), TYPE_XIVE_ROUTER)

typedef struct XiveRouterClass {
    SysBusDeviceClass parent;

    /* XIVE table accessors */
    int (*get_eas)(XiveRouter *xrtr, uint8_t eas_blk, uint32_t eas_idx,
                   XiveEAS *eas);
349 350 351 352
    int (*get_end)(XiveRouter *xrtr, uint8_t end_blk, uint32_t end_idx,
                   XiveEND *end);
    int (*write_end)(XiveRouter *xrtr, uint8_t end_blk, uint32_t end_idx,
                     XiveEND *end, uint8_t word_number);
353 354 355 356
    int (*get_nvt)(XiveRouter *xrtr, uint8_t nvt_blk, uint32_t nvt_idx,
                   XiveNVT *nvt);
    int (*write_nvt)(XiveRouter *xrtr, uint8_t nvt_blk, uint32_t nvt_idx,
                     XiveNVT *nvt, uint8_t word_number);
357
    XiveTCTX *(*get_tctx)(XiveRouter *xrtr, CPUState *cs);
358 359 360 361 362 363
} XiveRouterClass;

void xive_eas_pic_print_info(XiveEAS *eas, uint32_t lisn, Monitor *mon);

int xive_router_get_eas(XiveRouter *xrtr, uint8_t eas_blk, uint32_t eas_idx,
                        XiveEAS *eas);
364 365 366 367
int xive_router_get_end(XiveRouter *xrtr, uint8_t end_blk, uint32_t end_idx,
                        XiveEND *end);
int xive_router_write_end(XiveRouter *xrtr, uint8_t end_blk, uint32_t end_idx,
                          XiveEND *end, uint8_t word_number);
368 369 370 371
int xive_router_get_nvt(XiveRouter *xrtr, uint8_t nvt_blk, uint32_t nvt_idx,
                        XiveNVT *nvt);
int xive_router_write_nvt(XiveRouter *xrtr, uint8_t nvt_blk, uint32_t nvt_idx,
                          XiveNVT *nvt, uint8_t word_number);
372
XiveTCTX *xive_router_get_tctx(XiveRouter *xrtr, CPUState *cs);
373
void xive_router_notify(XiveNotifier *xn, uint32_t lisn);
374

375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395
/*
 * XIVE END ESBs
 */

#define TYPE_XIVE_END_SOURCE "xive-end-source"
#define XIVE_END_SOURCE(obj) \
    OBJECT_CHECK(XiveENDSource, (obj), TYPE_XIVE_END_SOURCE)

typedef struct XiveENDSource {
    DeviceState parent;

    uint32_t        nr_ends;
    uint8_t         block_id;

    /* ESB memory region */
    uint32_t        esb_shift;
    MemoryRegion    esb_mmio;

    XiveRouter      *xrtr;
} XiveENDSource;

396 397 398 399 400 401 402 403 404
/*
 * For legacy compatibility, the exceptions define up to 256 different
 * priorities. P9 implements only 9 levels : 8 active levels [0 - 7]
 * and the least favored level 0xFF.
 */
#define XIVE_PRIORITY_MAX  7

void xive_end_pic_print_info(XiveEND *end, uint32_t end_idx, Monitor *mon);
void xive_end_queue_pic_print_info(XiveEND *end, uint32_t width, Monitor *mon);
405

406 407 408 409 410 411 412 413 414 415 416 417 418 419
/*
 * XIVE Thread Interrupt Management Aera (TIMA)
 *
 * This region gives access to the registers of the thread interrupt
 * management context. It is four page wide, each page providing a
 * different view of the registers. The page with the lower offset is
 * the most privileged and gives access to the entire context.
 */
#define XIVE_TM_HW_PAGE         0x0
#define XIVE_TM_HV_PAGE         0x1
#define XIVE_TM_OS_PAGE         0x2
#define XIVE_TM_USER_PAGE       0x3

extern const MemoryRegionOps xive_tm_ops;
420 421 422
void xive_tctx_tm_write(XiveTCTX *tctx, hwaddr offset, uint64_t value,
                        unsigned size);
uint64_t xive_tctx_tm_read(XiveTCTX *tctx, hwaddr offset, unsigned size);
423 424

void xive_tctx_pic_print_info(XiveTCTX *tctx, Monitor *mon);
425
Object *xive_tctx_create(Object *cpu, XiveRouter *xrtr, Error **errp);
426

427 428 429 430 431
static inline uint32_t xive_nvt_cam_line(uint8_t nvt_blk, uint32_t nvt_idx)
{
    return (nvt_blk << 19) | nvt_idx;
}

C
Cédric Le Goater 已提交
432 433 434 435 436 437 438
/*
 * KVM XIVE device helpers
 */

void kvmppc_xive_source_reset_one(XiveSource *xsrc, int srcno, Error **errp);
void kvmppc_xive_source_set_irq(void *opaque, int srcno, int val);
void kvmppc_xive_cpu_connect(XiveTCTX *tctx, Error **errp);
439
void kvmppc_xive_cpu_synchronize_state(XiveTCTX *tctx, Error **errp);
440
void kvmppc_xive_cpu_get_state(XiveTCTX *tctx, Error **errp);
C
Cédric Le Goater 已提交
441

442
#endif /* PPC_XIVE_H */