linux/drivers/misc/cxl/cxl.h
<<
>>
Prefs
   1/*
   2 * Copyright 2014 IBM Corp.
   3 *
   4 * This program is free software; you can redistribute it and/or
   5 * modify it under the terms of the GNU General Public License
   6 * as published by the Free Software Foundation; either version
   7 * 2 of the License, or (at your option) any later version.
   8 */
   9
  10#ifndef _CXL_H_
  11#define _CXL_H_
  12
  13#include <linux/interrupt.h>
  14#include <linux/semaphore.h>
  15#include <linux/device.h>
  16#include <linux/types.h>
  17#include <linux/cdev.h>
  18#include <linux/pid.h>
  19#include <linux/io.h>
  20#include <linux/pci.h>
  21#include <asm/cputable.h>
  22#include <asm/mmu.h>
  23#include <asm/reg.h>
  24#include <misc/cxl.h>
  25
  26#include <uapi/misc/cxl.h>
  27
  28extern uint cxl_verbose;
  29
  30#define CXL_TIMEOUT 5
  31
  32/*
  33 * Bump version each time a user API change is made, whether it is
  34 * backwards compatible ot not.
  35 */
  36#define CXL_API_VERSION 1
  37#define CXL_API_VERSION_COMPATIBLE 1
  38
  39/*
  40 * Opaque types to avoid accidentally passing registers for the wrong MMIO
  41 *
  42 * At the end of the day, I'm not married to using typedef here, but it might
  43 * (and has!) help avoid bugs like mixing up CXL_PSL_CtxTime and
  44 * CXL_PSL_CtxTime_An, or calling cxl_p1n_write instead of cxl_p1_write.
  45 *
  46 * I'm quite happy if these are changed back to #defines before upstreaming, it
  47 * should be little more than a regexp search+replace operation in this file.
  48 */
  49typedef struct {
  50        const int x;
  51} cxl_p1_reg_t;
  52typedef struct {
  53        const int x;
  54} cxl_p1n_reg_t;
  55typedef struct {
  56        const int x;
  57} cxl_p2n_reg_t;
  58#define cxl_reg_off(reg) \
  59        (reg.x)
  60
  61/* Memory maps. Ref CXL Appendix A */
  62
  63/* PSL Privilege 1 Memory Map */
  64/* Configuration and Control area */
  65static const cxl_p1_reg_t CXL_PSL_CtxTime = {0x0000};
  66static const cxl_p1_reg_t CXL_PSL_ErrIVTE = {0x0008};
  67static const cxl_p1_reg_t CXL_PSL_KEY1    = {0x0010};
  68static const cxl_p1_reg_t CXL_PSL_KEY2    = {0x0018};
  69static const cxl_p1_reg_t CXL_PSL_Control = {0x0020};
  70/* Downloading */
  71static const cxl_p1_reg_t CXL_PSL_DLCNTL  = {0x0060};
  72static const cxl_p1_reg_t CXL_PSL_DLADDR  = {0x0068};
  73
  74/* PSL Lookaside Buffer Management Area */
  75static const cxl_p1_reg_t CXL_PSL_LBISEL  = {0x0080};
  76static const cxl_p1_reg_t CXL_PSL_SLBIE   = {0x0088};
  77static const cxl_p1_reg_t CXL_PSL_SLBIA   = {0x0090};
  78static const cxl_p1_reg_t CXL_PSL_TLBIE   = {0x00A0};
  79static const cxl_p1_reg_t CXL_PSL_TLBIA   = {0x00A8};
  80static const cxl_p1_reg_t CXL_PSL_AFUSEL  = {0x00B0};
  81
  82/* 0x00C0:7EFF Implementation dependent area */
  83static const cxl_p1_reg_t CXL_PSL_FIR1      = {0x0100};
  84static const cxl_p1_reg_t CXL_PSL_FIR2      = {0x0108};
  85static const cxl_p1_reg_t CXL_PSL_VERSION   = {0x0118};
  86static const cxl_p1_reg_t CXL_PSL_RESLCKTO  = {0x0128};
  87static const cxl_p1_reg_t CXL_PSL_FIR_CNTL  = {0x0148};
  88static const cxl_p1_reg_t CXL_PSL_DSNDCTL   = {0x0150};
  89static const cxl_p1_reg_t CXL_PSL_SNWRALLOC = {0x0158};
  90static const cxl_p1_reg_t CXL_PSL_TRACE     = {0x0170};
  91/* 0x7F00:7FFF Reserved PCIe MSI-X Pending Bit Array area */
  92/* 0x8000:FFFF Reserved PCIe MSI-X Table Area */
  93
  94/* PSL Slice Privilege 1 Memory Map */
  95/* Configuration Area */
  96static const cxl_p1n_reg_t CXL_PSL_SR_An          = {0x00};
  97static const cxl_p1n_reg_t CXL_PSL_LPID_An        = {0x08};
  98static const cxl_p1n_reg_t CXL_PSL_AMBAR_An       = {0x10};
  99static const cxl_p1n_reg_t CXL_PSL_SPOffset_An    = {0x18};
 100static const cxl_p1n_reg_t CXL_PSL_ID_An          = {0x20};
 101static const cxl_p1n_reg_t CXL_PSL_SERR_An        = {0x28};
 102/* Memory Management and Lookaside Buffer Management */
 103static const cxl_p1n_reg_t CXL_PSL_SDR_An         = {0x30};
 104static const cxl_p1n_reg_t CXL_PSL_AMOR_An        = {0x38};
 105/* Pointer Area */
 106static const cxl_p1n_reg_t CXL_HAURP_An           = {0x80};
 107static const cxl_p1n_reg_t CXL_PSL_SPAP_An        = {0x88};
 108static const cxl_p1n_reg_t CXL_PSL_LLCMD_An       = {0x90};
 109/* Control Area */
 110static const cxl_p1n_reg_t CXL_PSL_SCNTL_An       = {0xA0};
 111static const cxl_p1n_reg_t CXL_PSL_CtxTime_An     = {0xA8};
 112static const cxl_p1n_reg_t CXL_PSL_IVTE_Offset_An = {0xB0};
 113static const cxl_p1n_reg_t CXL_PSL_IVTE_Limit_An  = {0xB8};
 114/* 0xC0:FF Implementation Dependent Area */
 115static const cxl_p1n_reg_t CXL_PSL_FIR_SLICE_An   = {0xC0};
 116static const cxl_p1n_reg_t CXL_AFU_DEBUG_An       = {0xC8};
 117static const cxl_p1n_reg_t CXL_PSL_APCALLOC_A     = {0xD0};
 118static const cxl_p1n_reg_t CXL_PSL_COALLOC_A      = {0xD8};
 119static const cxl_p1n_reg_t CXL_PSL_RXCTL_A        = {0xE0};
 120static const cxl_p1n_reg_t CXL_PSL_SLICE_TRACE    = {0xE8};
 121
 122/* PSL Slice Privilege 2 Memory Map */
 123/* Configuration and Control Area */
 124static const cxl_p2n_reg_t CXL_PSL_PID_TID_An = {0x000};
 125static const cxl_p2n_reg_t CXL_CSRP_An        = {0x008};
 126static const cxl_p2n_reg_t CXL_AURP0_An       = {0x010};
 127static const cxl_p2n_reg_t CXL_AURP1_An       = {0x018};
 128static const cxl_p2n_reg_t CXL_SSTP0_An       = {0x020};
 129static const cxl_p2n_reg_t CXL_SSTP1_An       = {0x028};
 130static const cxl_p2n_reg_t CXL_PSL_AMR_An     = {0x030};
 131/* Segment Lookaside Buffer Management */
 132static const cxl_p2n_reg_t CXL_SLBIE_An       = {0x040};
 133static const cxl_p2n_reg_t CXL_SLBIA_An       = {0x048};
 134static const cxl_p2n_reg_t CXL_SLBI_Select_An = {0x050};
 135/* Interrupt Registers */
 136static const cxl_p2n_reg_t CXL_PSL_DSISR_An   = {0x060};
 137static const cxl_p2n_reg_t CXL_PSL_DAR_An     = {0x068};
 138static const cxl_p2n_reg_t CXL_PSL_DSR_An     = {0x070};
 139static const cxl_p2n_reg_t CXL_PSL_TFC_An     = {0x078};
 140static const cxl_p2n_reg_t CXL_PSL_PEHandle_An = {0x080};
 141static const cxl_p2n_reg_t CXL_PSL_ErrStat_An = {0x088};
 142/* AFU Registers */
 143static const cxl_p2n_reg_t CXL_AFU_Cntl_An    = {0x090};
 144static const cxl_p2n_reg_t CXL_AFU_ERR_An     = {0x098};
 145/* Work Element Descriptor */
 146static const cxl_p2n_reg_t CXL_PSL_WED_An     = {0x0A0};
 147/* 0x0C0:FFF Implementation Dependent Area */
 148
 149#define CXL_PSL_SPAP_Addr 0x0ffffffffffff000ULL
 150#define CXL_PSL_SPAP_Size 0x0000000000000ff0ULL
 151#define CXL_PSL_SPAP_Size_Shift 4
 152#define CXL_PSL_SPAP_V    0x0000000000000001ULL
 153
 154/****** CXL_PSL_DLCNTL *****************************************************/
 155#define CXL_PSL_DLCNTL_D (0x1ull << (63-28))
 156#define CXL_PSL_DLCNTL_C (0x1ull << (63-29))
 157#define CXL_PSL_DLCNTL_E (0x1ull << (63-30))
 158#define CXL_PSL_DLCNTL_S (0x1ull << (63-31))
 159#define CXL_PSL_DLCNTL_CE (CXL_PSL_DLCNTL_C | CXL_PSL_DLCNTL_E)
 160#define CXL_PSL_DLCNTL_DCES (CXL_PSL_DLCNTL_D | CXL_PSL_DLCNTL_CE | CXL_PSL_DLCNTL_S)
 161
 162/****** CXL_PSL_SR_An ******************************************************/
 163#define CXL_PSL_SR_An_SF  MSR_SF            /* 64bit */
 164#define CXL_PSL_SR_An_TA  (1ull << (63-1))  /* Tags active,   GA1: 0 */
 165#define CXL_PSL_SR_An_HV  MSR_HV            /* Hypervisor,    GA1: 0 */
 166#define CXL_PSL_SR_An_PR  MSR_PR            /* Problem state, GA1: 1 */
 167#define CXL_PSL_SR_An_ISL (1ull << (63-53)) /* Ignore Segment Large Page */
 168#define CXL_PSL_SR_An_TC  (1ull << (63-54)) /* Page Table secondary hash */
 169#define CXL_PSL_SR_An_US  (1ull << (63-56)) /* User state,    GA1: X */
 170#define CXL_PSL_SR_An_SC  (1ull << (63-58)) /* Segment Table secondary hash */
 171#define CXL_PSL_SR_An_R   MSR_DR            /* Relocate,      GA1: 1 */
 172#define CXL_PSL_SR_An_MP  (1ull << (63-62)) /* Master Process */
 173#define CXL_PSL_SR_An_LE  (1ull << (63-63)) /* Little Endian */
 174
 175/****** CXL_PSL_LLCMD_An ****************************************************/
 176#define CXL_LLCMD_TERMINATE   0x0001000000000000ULL
 177#define CXL_LLCMD_REMOVE      0x0002000000000000ULL
 178#define CXL_LLCMD_SUSPEND     0x0003000000000000ULL
 179#define CXL_LLCMD_RESUME      0x0004000000000000ULL
 180#define CXL_LLCMD_ADD         0x0005000000000000ULL
 181#define CXL_LLCMD_UPDATE      0x0006000000000000ULL
 182#define CXL_LLCMD_HANDLE_MASK 0x000000000000ffffULL
 183
 184/****** CXL_PSL_ID_An ****************************************************/
 185#define CXL_PSL_ID_An_F (1ull << (63-31))
 186#define CXL_PSL_ID_An_L (1ull << (63-30))
 187
 188/****** CXL_PSL_SCNTL_An ****************************************************/
 189#define CXL_PSL_SCNTL_An_CR          (0x1ull << (63-15))
 190/* Programming Modes: */
 191#define CXL_PSL_SCNTL_An_PM_MASK     (0xffffull << (63-31))
 192#define CXL_PSL_SCNTL_An_PM_Shared   (0x0000ull << (63-31))
 193#define CXL_PSL_SCNTL_An_PM_OS       (0x0001ull << (63-31))
 194#define CXL_PSL_SCNTL_An_PM_Process  (0x0002ull << (63-31))
 195#define CXL_PSL_SCNTL_An_PM_AFU      (0x0004ull << (63-31))
 196#define CXL_PSL_SCNTL_An_PM_AFU_PBT  (0x0104ull << (63-31))
 197/* Purge Status (ro) */
 198#define CXL_PSL_SCNTL_An_Ps_MASK     (0x3ull << (63-39))
 199#define CXL_PSL_SCNTL_An_Ps_Pending  (0x1ull << (63-39))
 200#define CXL_PSL_SCNTL_An_Ps_Complete (0x3ull << (63-39))
 201/* Purge */
 202#define CXL_PSL_SCNTL_An_Pc          (0x1ull << (63-48))
 203/* Suspend Status (ro) */
 204#define CXL_PSL_SCNTL_An_Ss_MASK     (0x3ull << (63-55))
 205#define CXL_PSL_SCNTL_An_Ss_Pending  (0x1ull << (63-55))
 206#define CXL_PSL_SCNTL_An_Ss_Complete (0x3ull << (63-55))
 207/* Suspend Control */
 208#define CXL_PSL_SCNTL_An_Sc          (0x1ull << (63-63))
 209
 210/* AFU Slice Enable Status (ro) */
 211#define CXL_AFU_Cntl_An_ES_MASK     (0x7ull << (63-2))
 212#define CXL_AFU_Cntl_An_ES_Disabled (0x0ull << (63-2))
 213#define CXL_AFU_Cntl_An_ES_Enabled  (0x4ull << (63-2))
 214/* AFU Slice Enable */
 215#define CXL_AFU_Cntl_An_E           (0x1ull << (63-3))
 216/* AFU Slice Reset status (ro) */
 217#define CXL_AFU_Cntl_An_RS_MASK     (0x3ull << (63-5))
 218#define CXL_AFU_Cntl_An_RS_Pending  (0x1ull << (63-5))
 219#define CXL_AFU_Cntl_An_RS_Complete (0x2ull << (63-5))
 220/* AFU Slice Reset */
 221#define CXL_AFU_Cntl_An_RA          (0x1ull << (63-7))
 222
 223/****** CXL_SSTP0/1_An ******************************************************/
 224/* These top bits are for the segment that CONTAINS the segment table */
 225#define CXL_SSTP0_An_B_SHIFT    SLB_VSID_SSIZE_SHIFT
 226#define CXL_SSTP0_An_KS             (1ull << (63-2))
 227#define CXL_SSTP0_An_KP             (1ull << (63-3))
 228#define CXL_SSTP0_An_N              (1ull << (63-4))
 229#define CXL_SSTP0_An_L              (1ull << (63-5))
 230#define CXL_SSTP0_An_C              (1ull << (63-6))
 231#define CXL_SSTP0_An_TA             (1ull << (63-7))
 232#define CXL_SSTP0_An_LP_SHIFT                (63-9)  /* 2 Bits */
 233/* And finally, the virtual address & size of the segment table: */
 234#define CXL_SSTP0_An_SegTableSize_SHIFT      (63-31) /* 12 Bits */
 235#define CXL_SSTP0_An_SegTableSize_MASK \
 236        (((1ull << 12) - 1) << CXL_SSTP0_An_SegTableSize_SHIFT)
 237#define CXL_SSTP0_An_STVA_U_MASK   ((1ull << (63-49))-1)
 238#define CXL_SSTP1_An_STVA_L_MASK (~((1ull << (63-55))-1))
 239#define CXL_SSTP1_An_V              (1ull << (63-63))
 240
 241/****** CXL_PSL_SLBIE_[An] **************************************************/
 242/* write: */
 243#define CXL_SLBIE_C        PPC_BIT(36)         /* Class */
 244#define CXL_SLBIE_SS       PPC_BITMASK(37, 38) /* Segment Size */
 245#define CXL_SLBIE_SS_SHIFT PPC_BITLSHIFT(38)
 246#define CXL_SLBIE_TA       PPC_BIT(38)         /* Tags Active */
 247/* read: */
 248#define CXL_SLBIE_MAX      PPC_BITMASK(24, 31)
 249#define CXL_SLBIE_PENDING  PPC_BITMASK(56, 63)
 250
 251/****** Common to all CXL_TLBIA/SLBIA_[An] **********************************/
 252#define CXL_TLB_SLB_P          (1ull) /* Pending (read) */
 253
 254/****** Common to all CXL_TLB/SLB_IA/IE_[An] registers **********************/
 255#define CXL_TLB_SLB_IQ_ALL     (0ull) /* Inv qualifier */
 256#define CXL_TLB_SLB_IQ_LPID    (1ull) /* Inv qualifier */
 257#define CXL_TLB_SLB_IQ_LPIDPID (3ull) /* Inv qualifier */
 258
 259/****** CXL_PSL_AFUSEL ******************************************************/
 260#define CXL_PSL_AFUSEL_A (1ull << (63-55)) /* Adapter wide invalidates affect all AFUs */
 261
 262/****** CXL_PSL_DSISR_An ****************************************************/
 263#define CXL_PSL_DSISR_An_DS (1ull << (63-0))  /* Segment not found */
 264#define CXL_PSL_DSISR_An_DM (1ull << (63-1))  /* PTE not found (See also: M) or protection fault */
 265#define CXL_PSL_DSISR_An_ST (1ull << (63-2))  /* Segment Table PTE not found */
 266#define CXL_PSL_DSISR_An_UR (1ull << (63-3))  /* AURP PTE not found */
 267#define CXL_PSL_DSISR_TRANS (CXL_PSL_DSISR_An_DS | CXL_PSL_DSISR_An_DM | CXL_PSL_DSISR_An_ST | CXL_PSL_DSISR_An_UR)
 268#define CXL_PSL_DSISR_An_PE (1ull << (63-4))  /* PSL Error (implementation specific) */
 269#define CXL_PSL_DSISR_An_AE (1ull << (63-5))  /* AFU Error */
 270#define CXL_PSL_DSISR_An_OC (1ull << (63-6))  /* OS Context Warning */
 271/* NOTE: Bits 32:63 are undefined if DSISR[DS] = 1 */
 272#define CXL_PSL_DSISR_An_M  DSISR_NOHPTE      /* PTE not found */
 273#define CXL_PSL_DSISR_An_P  DSISR_PROTFAULT   /* Storage protection violation */
 274#define CXL_PSL_DSISR_An_A  (1ull << (63-37)) /* AFU lock access to write through or cache inhibited storage */
 275#define CXL_PSL_DSISR_An_S  DSISR_ISSTORE     /* Access was afu_wr or afu_zero */
 276#define CXL_PSL_DSISR_An_K  DSISR_KEYFAULT    /* Access not permitted by virtual page class key protection */
 277
 278/****** CXL_PSL_TFC_An ******************************************************/
 279#define CXL_PSL_TFC_An_A  (1ull << (63-28)) /* Acknowledge non-translation fault */
 280#define CXL_PSL_TFC_An_C  (1ull << (63-29)) /* Continue (abort transaction) */
 281#define CXL_PSL_TFC_An_AE (1ull << (63-30)) /* Restart PSL with address error */
 282#define CXL_PSL_TFC_An_R  (1ull << (63-31)) /* Restart PSL transaction */
 283
 284/* cxl_process_element->software_status */
 285#define CXL_PE_SOFTWARE_STATE_V (1ul << (31 -  0)) /* Valid */
 286#define CXL_PE_SOFTWARE_STATE_C (1ul << (31 - 29)) /* Complete */
 287#define CXL_PE_SOFTWARE_STATE_S (1ul << (31 - 30)) /* Suspend */
 288#define CXL_PE_SOFTWARE_STATE_T (1ul << (31 - 31)) /* Terminate */
 289
 290/****** CXL_PSL_RXCTL_An (Implementation Specific) **************************
 291 * Controls AFU Hang Pulse, which sets the timeout for the AFU to respond to
 292 * the PSL for any response (except MMIO). Timeouts will occur between 1x to 2x
 293 * of the hang pulse frequency.
 294 */
 295#define CXL_PSL_RXCTL_AFUHP_4S      0x7000000000000000ULL
 296
 297/* SPA->sw_command_status */
 298#define CXL_SPA_SW_CMD_MASK         0xffff000000000000ULL
 299#define CXL_SPA_SW_CMD_TERMINATE    0x0001000000000000ULL
 300#define CXL_SPA_SW_CMD_REMOVE       0x0002000000000000ULL
 301#define CXL_SPA_SW_CMD_SUSPEND      0x0003000000000000ULL
 302#define CXL_SPA_SW_CMD_RESUME       0x0004000000000000ULL
 303#define CXL_SPA_SW_CMD_ADD          0x0005000000000000ULL
 304#define CXL_SPA_SW_CMD_UPDATE       0x0006000000000000ULL
 305#define CXL_SPA_SW_STATE_MASK       0x0000ffff00000000ULL
 306#define CXL_SPA_SW_STATE_TERMINATED 0x0000000100000000ULL
 307#define CXL_SPA_SW_STATE_REMOVED    0x0000000200000000ULL
 308#define CXL_SPA_SW_STATE_SUSPENDED  0x0000000300000000ULL
 309#define CXL_SPA_SW_STATE_RESUMED    0x0000000400000000ULL
 310#define CXL_SPA_SW_STATE_ADDED      0x0000000500000000ULL
 311#define CXL_SPA_SW_STATE_UPDATED    0x0000000600000000ULL
 312#define CXL_SPA_SW_PSL_ID_MASK      0x00000000ffff0000ULL
 313#define CXL_SPA_SW_LINK_MASK        0x000000000000ffffULL
 314
 315#define CXL_MAX_SLICES 4
 316#define MAX_AFU_MMIO_REGS 3
 317
 318#define CXL_MODE_DEDICATED   0x1
 319#define CXL_MODE_DIRECTED    0x2
 320#define CXL_MODE_TIME_SLICED 0x4
 321#define CXL_SUPPORTED_MODES (CXL_MODE_DEDICATED | CXL_MODE_DIRECTED)
 322
 323enum cxl_context_status {
 324        CLOSED,
 325        OPENED,
 326        STARTED
 327};
 328
 329enum prefault_modes {
 330        CXL_PREFAULT_NONE,
 331        CXL_PREFAULT_WED,
 332        CXL_PREFAULT_ALL,
 333};
 334
 335struct cxl_sste {
 336        __be64 esid_data;
 337        __be64 vsid_data;
 338};
 339
 340#define to_cxl_adapter(d) container_of(d, struct cxl, dev)
 341#define to_cxl_afu(d) container_of(d, struct cxl_afu, dev)
 342
 343struct cxl_afu {
 344        irq_hw_number_t psl_hwirq;
 345        irq_hw_number_t serr_hwirq;
 346        char *err_irq_name;
 347        char *psl_irq_name;
 348        unsigned int serr_virq;
 349        void __iomem *p1n_mmio;
 350        void __iomem *p2n_mmio;
 351        phys_addr_t psn_phys;
 352        u64 pp_offset;
 353        u64 pp_size;
 354        void __iomem *afu_desc_mmio;
 355        struct cxl *adapter;
 356        struct device dev;
 357        struct cdev afu_cdev_s, afu_cdev_m, afu_cdev_d;
 358        struct device *chardev_s, *chardev_m, *chardev_d;
 359        struct idr contexts_idr;
 360        struct dentry *debugfs;
 361        struct mutex contexts_lock;
 362        struct mutex spa_mutex;
 363        spinlock_t afu_cntl_lock;
 364
 365        /*
 366         * Only the first part of the SPA is used for the process element
 367         * linked list. The only other part that software needs to worry about
 368         * is sw_command_status, which we store a separate pointer to.
 369         * Everything else in the SPA is only used by hardware
 370         */
 371        struct cxl_process_element *spa;
 372        __be64 *sw_command_status;
 373        unsigned int spa_size;
 374        int spa_order;
 375        int spa_max_procs;
 376        unsigned int psl_virq;
 377
 378        int pp_irqs;
 379        int irqs_max;
 380        int num_procs;
 381        int max_procs_virtualised;
 382        int slice;
 383        int modes_supported;
 384        int current_mode;
 385        int crs_num;
 386        u64 crs_len;
 387        u64 crs_offset;
 388        struct list_head crs;
 389        enum prefault_modes prefault_mode;
 390        bool psa;
 391        bool pp_psa;
 392        bool enabled;
 393};
 394
 395
 396struct cxl_irq_name {
 397        struct list_head list;
 398        char *name;
 399};
 400
 401/*
 402 * This is a cxl context.  If the PSL is in dedicated mode, there will be one
 403 * of these per AFU.  If in AFU directed there can be lots of these.
 404 */
 405struct cxl_context {
 406        struct cxl_afu *afu;
 407
 408        /* Problem state MMIO */
 409        phys_addr_t psn_phys;
 410        u64 psn_size;
 411
 412        /* Used to unmap any mmaps when force detaching */
 413        struct address_space *mapping;
 414        struct mutex mapping_lock;
 415
 416        spinlock_t sste_lock; /* Protects segment table entries */
 417        struct cxl_sste *sstp;
 418        u64 sstp0, sstp1;
 419        unsigned int sst_size, sst_lru;
 420
 421        wait_queue_head_t wq;
 422        struct pid *pid;
 423        spinlock_t lock; /* Protects pending_irq_mask, pending_fault and fault_addr */
 424        /* Only used in PR mode */
 425        u64 process_token;
 426
 427        unsigned long *irq_bitmap; /* Accessed from IRQ context */
 428        struct cxl_irq_ranges irqs;
 429        struct list_head irq_names;
 430        u64 fault_addr;
 431        u64 fault_dsisr;
 432        u64 afu_err;
 433
 434        /*
 435         * This status and it's lock pretects start and detach context
 436         * from racing.  It also prevents detach from racing with
 437         * itself
 438         */
 439        enum cxl_context_status status;
 440        struct mutex status_mutex;
 441
 442
 443        /* XXX: Is it possible to need multiple work items at once? */
 444        struct work_struct fault_work;
 445        u64 dsisr;
 446        u64 dar;
 447
 448        struct cxl_process_element *elem;
 449
 450        int pe; /* process element handle */
 451        u32 irq_count;
 452        bool pe_inserted;
 453        bool master;
 454        bool kernel;
 455        bool pending_irq;
 456        bool pending_fault;
 457        bool pending_afu_err;
 458};
 459
 460struct cxl {
 461        void __iomem *p1_mmio;
 462        void __iomem *p2_mmio;
 463        irq_hw_number_t err_hwirq;
 464        unsigned int err_virq;
 465        spinlock_t afu_list_lock;
 466        struct cxl_afu *afu[CXL_MAX_SLICES];
 467        struct device dev;
 468        struct dentry *trace;
 469        struct dentry *psl_err_chk;
 470        struct dentry *debugfs;
 471        char *irq_name;
 472        struct bin_attribute cxl_attr;
 473        int adapter_num;
 474        int user_irqs;
 475        u64 afu_desc_off;
 476        u64 afu_desc_size;
 477        u64 ps_off;
 478        u64 ps_size;
 479        u16 psl_rev;
 480        u16 base_image;
 481        u8 vsec_status;
 482        u8 caia_major;
 483        u8 caia_minor;
 484        u8 slices;
 485        bool user_image_loaded;
 486        bool perst_loads_image;
 487        bool perst_select_user;
 488};
 489
 490int cxl_alloc_one_irq(struct cxl *adapter);
 491void cxl_release_one_irq(struct cxl *adapter, int hwirq);
 492int cxl_alloc_irq_ranges(struct cxl_irq_ranges *irqs, struct cxl *adapter, unsigned int num);
 493void cxl_release_irq_ranges(struct cxl_irq_ranges *irqs, struct cxl *adapter);
 494int cxl_setup_irq(struct cxl *adapter, unsigned int hwirq, unsigned int virq);
 495int cxl_update_image_control(struct cxl *adapter);
 496int cxl_reset(struct cxl *adapter);
 497
 498/* common == phyp + powernv */
 499struct cxl_process_element_common {
 500        __be32 tid;
 501        __be32 pid;
 502        __be64 csrp;
 503        __be64 aurp0;
 504        __be64 aurp1;
 505        __be64 sstp0;
 506        __be64 sstp1;
 507        __be64 amr;
 508        u8     reserved3[4];
 509        __be64 wed;
 510} __packed;
 511
 512/* just powernv */
 513struct cxl_process_element {
 514        __be64 sr;
 515        __be64 SPOffset;
 516        __be64 sdr;
 517        __be64 haurp;
 518        __be32 ctxtime;
 519        __be16 ivte_offsets[4];
 520        __be16 ivte_ranges[4];
 521        __be32 lpid;
 522        struct cxl_process_element_common common;
 523        __be32 software_state;
 524} __packed;
 525
 526static inline void __iomem *_cxl_p1_addr(struct cxl *cxl, cxl_p1_reg_t reg)
 527{
 528        WARN_ON(!cpu_has_feature(CPU_FTR_HVMODE));
 529        return cxl->p1_mmio + cxl_reg_off(reg);
 530}
 531
 532#define cxl_p1_write(cxl, reg, val) \
 533        out_be64(_cxl_p1_addr(cxl, reg), val)
 534#define cxl_p1_read(cxl, reg) \
 535        in_be64(_cxl_p1_addr(cxl, reg))
 536
 537static inline void __iomem *_cxl_p1n_addr(struct cxl_afu *afu, cxl_p1n_reg_t reg)
 538{
 539        WARN_ON(!cpu_has_feature(CPU_FTR_HVMODE));
 540        return afu->p1n_mmio + cxl_reg_off(reg);
 541}
 542
 543#define cxl_p1n_write(afu, reg, val) \
 544        out_be64(_cxl_p1n_addr(afu, reg), val)
 545#define cxl_p1n_read(afu, reg) \
 546        in_be64(_cxl_p1n_addr(afu, reg))
 547
 548static inline void __iomem *_cxl_p2n_addr(struct cxl_afu *afu, cxl_p2n_reg_t reg)
 549{
 550        return afu->p2n_mmio + cxl_reg_off(reg);
 551}
 552
 553#define cxl_p2n_write(afu, reg, val) \
 554        out_be64(_cxl_p2n_addr(afu, reg), val)
 555#define cxl_p2n_read(afu, reg) \
 556        in_be64(_cxl_p2n_addr(afu, reg))
 557
 558
 559#define cxl_afu_cr_read64(afu, cr, off) \
 560        in_le64((afu)->afu_desc_mmio + (afu)->crs_offset + ((cr) * (afu)->crs_len) + (off))
 561#define cxl_afu_cr_read32(afu, cr, off) \
 562        in_le32((afu)->afu_desc_mmio + (afu)->crs_offset + ((cr) * (afu)->crs_len) + (off))
 563u16 cxl_afu_cr_read16(struct cxl_afu *afu, int cr, u64 off);
 564u8 cxl_afu_cr_read8(struct cxl_afu *afu, int cr, u64 off);
 565
 566
 567struct cxl_calls {
 568        void (*cxl_slbia)(struct mm_struct *mm);
 569        struct module *owner;
 570};
 571int register_cxl_calls(struct cxl_calls *calls);
 572void unregister_cxl_calls(struct cxl_calls *calls);
 573
 574int cxl_alloc_adapter_nr(struct cxl *adapter);
 575void cxl_remove_adapter_nr(struct cxl *adapter);
 576
 577int cxl_file_init(void);
 578void cxl_file_exit(void);
 579int cxl_register_adapter(struct cxl *adapter);
 580int cxl_register_afu(struct cxl_afu *afu);
 581int cxl_chardev_d_afu_add(struct cxl_afu *afu);
 582int cxl_chardev_m_afu_add(struct cxl_afu *afu);
 583int cxl_chardev_s_afu_add(struct cxl_afu *afu);
 584void cxl_chardev_afu_remove(struct cxl_afu *afu);
 585
 586void cxl_context_detach_all(struct cxl_afu *afu);
 587void cxl_context_free(struct cxl_context *ctx);
 588void cxl_context_detach(struct cxl_context *ctx);
 589
 590int cxl_sysfs_adapter_add(struct cxl *adapter);
 591void cxl_sysfs_adapter_remove(struct cxl *adapter);
 592int cxl_sysfs_afu_add(struct cxl_afu *afu);
 593void cxl_sysfs_afu_remove(struct cxl_afu *afu);
 594int cxl_sysfs_afu_m_add(struct cxl_afu *afu);
 595void cxl_sysfs_afu_m_remove(struct cxl_afu *afu);
 596
 597int cxl_afu_activate_mode(struct cxl_afu *afu, int mode);
 598int _cxl_afu_deactivate_mode(struct cxl_afu *afu, int mode);
 599int cxl_afu_deactivate_mode(struct cxl_afu *afu);
 600int cxl_afu_select_best_mode(struct cxl_afu *afu);
 601
 602int cxl_register_psl_irq(struct cxl_afu *afu);
 603void cxl_release_psl_irq(struct cxl_afu *afu);
 604int cxl_register_psl_err_irq(struct cxl *adapter);
 605void cxl_release_psl_err_irq(struct cxl *adapter);
 606int cxl_register_serr_irq(struct cxl_afu *afu);
 607void cxl_release_serr_irq(struct cxl_afu *afu);
 608int afu_register_irqs(struct cxl_context *ctx, u32 count);
 609void afu_release_irqs(struct cxl_context *ctx);
 610irqreturn_t cxl_slice_irq_err(int irq, void *data);
 611
 612int cxl_debugfs_init(void);
 613void cxl_debugfs_exit(void);
 614int cxl_debugfs_adapter_add(struct cxl *adapter);
 615void cxl_debugfs_adapter_remove(struct cxl *adapter);
 616int cxl_debugfs_afu_add(struct cxl_afu *afu);
 617void cxl_debugfs_afu_remove(struct cxl_afu *afu);
 618
 619void cxl_handle_fault(struct work_struct *work);
 620void cxl_prefault(struct cxl_context *ctx, u64 wed);
 621
 622struct cxl *get_cxl_adapter(int num);
 623int cxl_alloc_sst(struct cxl_context *ctx);
 624
 625void init_cxl_native(void);
 626
 627struct cxl_context *cxl_context_alloc(void);
 628int cxl_context_init(struct cxl_context *ctx, struct cxl_afu *afu, bool master,
 629                     struct address_space *mapping);
 630void cxl_context_free(struct cxl_context *ctx);
 631int cxl_context_iomap(struct cxl_context *ctx, struct vm_area_struct *vma);
 632
 633/* This matches the layout of the H_COLLECT_CA_INT_INFO retbuf */
 634struct cxl_irq_info {
 635        u64 dsisr;
 636        u64 dar;
 637        u64 dsr;
 638        u32 pid;
 639        u32 tid;
 640        u64 afu_err;
 641        u64 errstat;
 642        u64 padding[3]; /* to match the expected retbuf size for plpar_hcall9 */
 643};
 644
 645int cxl_attach_process(struct cxl_context *ctx, bool kernel, u64 wed,
 646                            u64 amr);
 647int cxl_detach_process(struct cxl_context *ctx);
 648
 649int cxl_get_irq(struct cxl_afu *afu, struct cxl_irq_info *info);
 650int cxl_ack_irq(struct cxl_context *ctx, u64 tfc, u64 psl_reset_mask);
 651
 652int cxl_check_error(struct cxl_afu *afu);
 653int cxl_afu_slbia(struct cxl_afu *afu);
 654int cxl_tlb_slb_invalidate(struct cxl *adapter);
 655int cxl_afu_disable(struct cxl_afu *afu);
 656int cxl_afu_reset(struct cxl_afu *afu);
 657int cxl_psl_purge(struct cxl_afu *afu);
 658
 659void cxl_stop_trace(struct cxl *cxl);
 660
 661extern struct pci_driver cxl_pci_driver;
 662
 663#endif
 664