1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 #ifndef _ZULUMOD_H
  27 #define _ZULUMOD_H
  28 
  29 #pragma ident   "%Z%%M% %I%     %E% SMI"
  30 
  31 #ifdef  __cplusplus
  32 extern "C" {
  33 #endif
  34 
  35 #include <sys/int_const.h>
  36 #include <sys/zuluvm.h>
  37 
  38 #ifndef _ASM
  39 
  40 #include <sys/zulu_hat.h>
  41 #include <sys/sysmacros.h>
  42 
  43 #define ZULUVM_VERSION_STR(a)   #a
  44 #define ZULUVM_VERSION(a)       ZULUVM_VERSION_STR(a)
  45 #define ZULUVM_MOD_VERSION \
  46         ZULUVM_VERSION(XHAT_PROVIDER_VERSION) "." \
  47         ZULUVM_VERSION(ZULUVM_INTERFACE_VERSION)
  48 
  49 #define ZULUDCHKFUNC(_p1, _p2, _p3) \
  50         ((_p1) != NULL && (_p1)->_p2 != NULL) ? \
  51         (_p1)->_p2 _p3 : ZULUVM_NO_SUPPORT
  52 #define ZULUDCHKPROC(_p1, _p2, _p3) \
  53         if ((_p1) != NULL && (_p1)->_p2 != NULL) (_p1)->_p2 _p3
  54 
  55 #define zulud_set_itlb_pc(_devp, _a, _b) \
  56         ZULUDCHKPROC((_devp)->dops, set_itlb_pc, (_a, _b))
  57 #define zulud_set_dtlb_pc(_devp, _a, _b) \
  58         ZULUDCHKPROC((_devp)->dops, set_dtlb_pc, (_a, _b))
  59 #define zulud_write_tte(_devp, _a, _b, _c, _d, _e, _f) \
  60         ZULUDCHKFUNC((_devp)->dops, write_tte, (_a, _b, _c, _d, _e, _f))
  61 #define zulud_tlb_done(_devp, _a, _b, _c) \
  62         ZULUDCHKPROC((_devp)->dops, tlb_done, (_a, _b, _c))
  63 #define zulud_demap_page(_devp, _a, _b, _c) \
  64         ZULUDCHKPROC((_devp)->dops, demap_page, (_a, _b, _c))
  65 #define zulud_demap_ctx(_devp, _a, _b) \
  66         ZULUDCHKPROC((_devp)->dops, demap_ctx, (_a, _b))
  67 
  68 #endif
  69 
  70 #define ZULUVM_DATA0_IDX        0
  71 #define ZULUVM_DATA1_IDX        1
  72 #define ZULUVM_DATA2_IDX        2
  73 #define ZULUVM_DATA3_IDX        3
  74 #define ZULUVM_DATA4_IDX        4
  75 #define ZULUVM_DATA5_IDX        5
  76 #define ZULUVM_DATA6_IDX        6
  77 #define ZULUVM_DATA7_IDX        7
  78 
  79 #define ZULUVM_IDX2FLAG(i)      (1 << (7 - i))
  80 #define ZULUVM_DATA0_FLAG       ZULUVM_IDX2FLAG(ZULUVM_DATA0_IDX)
  81 #define ZULUVM_DATA1_FLAG       ZULUVM_IDX2FLAG(ZULUVM_DATA1_IDX)
  82 #define ZULUVM_DATA2_FLAG       ZULUVM_IDX2FLAG(ZULUVM_DATA2_IDX)
  83 #define ZULUVM_DATA3_FLAG       ZULUVM_IDX2FLAG(ZULUVM_DATA3_IDX)
  84 #define ZULUVM_DATA4_FLAG       ZULUVM_IDX2FLAG(ZULUVM_DATA4_IDX)
  85 #define ZULUVM_DATA5_FLAG       ZULUVM_IDX2FLAG(ZULUVM_DATA5_IDX)
  86 #define ZULUVM_DATA6_FLAG       ZULUVM_IDX2FLAG(ZULUVM_DATA6_IDX)
  87 #define ZULUVM_DATA7_FLAG       ZULUVM_IDX2FLAG(ZULUVM_DATA7_IDX)
  88 
  89 #define ZULUVM_TLB_ADDR_IDX     ZULUVM_DATA0_IDX
  90 #define ZULUVM_TLB_TYPE_IDX     ZULUVM_DATA1_IDX
  91 #define ZULUVM_TLB_TTE_IDX      ZULUVM_DATA2_IDX
  92 #define ZULUVM_TLB_ERRCODE_IDX  ZULUVM_DATA3_IDX
  93 
  94 #define ZULUVM_DATA_FLAGS       (ZULUVM_DATA1_FLAG | \
  95                                 ZULUVM_DATA6_FLAG)
  96 
  97 #define ZULUVM_GET_TLB_TTE(devp) \
  98                 (devp)->zvm.idata[ZULUVM_TLB_TTE_IDX]
  99 #define ZULUVM_GET_TLB_ADDR(devp) \
 100                 (devp)->zvm.idata[ZULUVM_TLB_ADDR_IDX]
 101 #define ZULUVM_GET_TLB_TYPE(devp) (ZULUVM_DMA_MASK & \
 102                 (devp)->zvm.idata[ZULUVM_TLB_TYPE_IDX])
 103 #define ZULUVM_GET_TLB_ERRCODE(devp) (int)(0xffffffff & \
 104                 (devp)->zvm.idata[ZULUVM_TLB_ERRCODE_IDX])
 105 
 106 #define ZULUVM_MAX_DEV          2
 107 #define ZULUVM_PIL              PIL_2
 108 #define ZULUVM_NUM_PGSZS        4
 109 
 110 #define ZULUVM_STATE_IDLE               0
 111 #define ZULUVM_STATE_STOPPED            1
 112 #define ZULUVM_STATE_CANCELED           2
 113 #define ZULUVM_STATE_TLB_PENDING        3
 114 #define ZULUVM_STATE_INTR_QUEUED        4
 115 #define ZULUVM_STATE_INTR_PENDING       5
 116 #define ZULUVM_STATE_WRITE_TTE          6
 117 
 118 #ifndef _ASM
 119 
 120 typedef struct {
 121         uint64_t        idata[4];       /* mondo pkt copy area */
 122         void            *arg;           /* arg for device calls */
 123         uint64_t        mmu_pa;         /* phy. addr of MMU regs */
 124         struct zuluvm_proc *proc1;
 125         struct zuluvm_proc *proc2;
 126         volatile uint32_t state;        /* state of tlb miss handling */
 127         uint64_t        intr_num;       /* our soft intr number */
 128         short           dmv_intr;       /* dmv interrupt handle */
 129 #ifdef ZULUVM_STATS
 130         int             cancel;
 131         int             tlb_miss[ZULUVM_NUM_PGSZS];
 132         int             pagefault;
 133         int             no_mapping;
 134         int             preload;
 135         int             migrate;
 136         int             pagesize;
 137         int             itlb1miss;
 138         int             dtlb1miss;
 139         int             itlb2miss;
 140         int             dtlb2miss;
 141         int             demap_page;
 142         int             demap_ctx;
 143 #endif
 144         uint64_t        pfnbuf[50];
 145         int             pfncnt;
 146 } zuluvm_miss_t;
 147 
 148 #ifdef ZULUVM_STATS
 149 #define ZULUVM_STATS_MISS(devp, sz)     (devp)->zvm.tlb_miss[sz]++
 150 #define ZULUVM_STATS_PAGEFAULT(devp)    (devp)->zvm.pagefault++
 151 #define ZULUVM_STATS_NOMAP(devp)        (devp)->zvm.no_mapping++
 152 #define ZULUVM_STATS_PRELOAD(devp)      (devp)->zvm.preload++
 153 #define ZULUVM_STATS_MIGRATE(devp)      (devp)->zvm.migrate++
 154 #define ZULUVM_STATS_PAGEZISE(devp)     (devp)->zvm.pagesize++
 155 #define ZULUVM_STATS_CANCEL(devp)       (devp)->zvm.cancel++
 156 #define ZULUVM_STATS_DEMAP_PAGE(devp)   (devp)->zvm.demap_page++
 157 #define ZULUVM_STATS_DEMAP_CTX(devp)    (devp)->zvm.demap_ctx++
 158 #else
 159 #define ZULUVM_STATS_MISS(devp, sz)
 160 #define ZULUVM_STATS_PAGEFAULT(devp)
 161 #define ZULUVM_STATS_NOMAP(devp)
 162 #define ZULUVM_STATS_PRELOAD(devp)
 163 #define ZULUVM_STATS_MIGRATE(devp)
 164 #define ZULUVM_STATS_PAGEZISE(devp)
 165 #define ZULUVM_STATS_CANCEL(devp)
 166 #define ZULUVM_STATS_DEMAP_PAGE(devp)
 167 #define ZULUVM_STATS_DEMAP_CTX(devp)
 168 #endif
 169 
 170 #define ZULUVM_MAX_INTR 32
 171 
 172 typedef struct {
 173         short offset;
 174         short ino;
 175 } zuluvm_intr_t;
 176 
 177 /*
 178  * This structure contains per device data.
 179  * It is protected by dev_lck.
 180  */
 181 typedef struct {
 182         zuluvm_miss_t           zvm;            /* tlb miss state */
 183         volatile uint64_t       *imr;           /* intr mapping regs */
 184         struct zuluvm_proc      *procs;         /* protected by proc_lck */
 185         dev_info_t              *dip;           /* device driver instance */
 186         zulud_ops_t             *dops;          /* device drv operations */
 187         kmutex_t                load_lck;       /* protects in_intr */
 188         kmutex_t                dev_lck;        /* protects this struct */
 189         kmutex_t                proc_lck;       /* protects active procs */
 190         kcondvar_t              intr_wait;      /* sync for as_free */
 191         int                     intr_flags;
 192         int                     in_intr;
 193         kmutex_t                park_lck;       /* page fault thread */
 194         kcondvar_t              park_cv;
 195         int                     parking;
 196         int                     agentid;        /* zulu's agent id */
 197         zuluvm_intr_t           interrupts[ZULUVM_MAX_INTR];
 198 } zuluvm_state_t;
 199 
 200 #define ZULUVM_INTR_OFFSET      offsetof(zuluvm_state_t, interrupts)
 201 #define ZULUVM_INTR2INO(addr)   (((zuluvm_intr_t *)(addr))->ino)
 202 #define ZULUVM_INTR2ZDEV(addr) \
 203         (zuluvm_state_t *)((caddr_t)addr - (ZULUVM_INTR2INO(addr) * \
 204         sizeof (zuluvm_intr_t)) - ZULUVM_INTR_OFFSET)
 205 
 206 typedef struct zuluvm_proc {
 207         struct zulu_hat *zhat;
 208         zuluvm_state_t  *zdev;  /* back ptr to dev instance */
 209         unsigned short  refcnt; /* keep this until ref == 0 */
 210         short           valid;  /* if valid is 0 then don't use */
 211         struct zuluvm_proc *next;
 212         struct zuluvm_proc *prev;
 213 } zuluvm_proc_t;
 214 
 215 #define ZULUVM_DO_INTR1         INT32_C(1)
 216 #define ZULUVM_WAIT_INTR1       INT32_C(2)
 217 #define ZULUVM_DO_INTR2         INT32_C(4)
 218 #define ZULUVM_WAIT_INTR2       INT32_C(8)
 219 
 220 int zuluvm_change_state(uint32_t *state_pa, int new, int assume);
 221 void zuluvm_demap_page(void *, struct hat *, short, caddr_t, uint_t);
 222 void zuluvm_demap_ctx(void *, short);
 223 void zuluvm_dmv_tlbmiss_tl1(void);
 224 void zuluvm_load_tte(struct zulu_hat *zhat, caddr_t addr, uint64_t pfn,
 225                 int perm, int size);
 226 
 227 
 228 #endif
 229 
 230 /*
 231  * The following defines are copied from the ZFB and ZULU
 232  * workspaces. We re-define them here since we can't have
 233  * a dependency onto files outside our consolidation
 234  */
 235 #define ZULUVM_IMR_V_MASK       UINT64_C(0x0000000080000000)
 236 #define ZULUVM_IMR_TARGET_SHIFT INT32_C(26)
 237 #define ZULUVM_IMR_MAX          INT32_C(0x3f)
 238 
 239 #define ZULUVM_ZFB_MMU_TLB_D_V_MASK       0x8000000000000000
 240 #define ZULUVM_ZFB_MMU_TLB_D_PA_SHIFT     0xD   /* 13 bits */
 241 #define ZULUVM_ZFB_MMU_TLB_D_C_MASK       0x20
 242 #define ZULUVM_ZFB_MMU_TLB_D_SZ_SHIFT     0x3D  /* 61 */
 243 #define ZULUVM_ZFB_MMU_TLB_D_SZ_MASK      0x6000000000000000
 244 #define ZULUVM_ZFB_MMU_TLB_D_W_MASK       0x2
 245 #define ZULUVM_ZFB_MMU_TLB_CR_IMISS_MASK  0x2
 246 #define ZULUVM_ZFB_MMU_TLB_CR_DMISS_MASK  0x1
 247 #define ZULUVM_ZFB_MMU_DTLB_PAGE_SZ_2_MASK  0xc /* DTLB2 Page size */
 248 #define ZULUVM_ZFB_MMU_DTLB_PAGE_SZ_2_SHIFT 2
 249 #define ZULUVM_DTLB_PAGE_SZ     0x8
 250 #define ZULUVM_ITLB_DATA_IN     0x18
 251 #define ZULUVM_DTLB_DATA_IN     0x28
 252 #define ZULUVM_TLB_CONTROL      0
 253 #define ZULUVM_ITLB_MISS_ICR    0x0
 254 #define ZULUVM_DTLB_MISS_ICR    0x8
 255 #define ZULUVM_DMA1_TSB_BASE    0x50
 256 #define ZULUVM_DMA2_TSB_BASE    0x68
 257 
 258 #ifdef  __cplusplus
 259 }
 260 #endif
 261 
 262 #endif  /* _ZULUMOD_H */