Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 /*
0003  * SN Platform GRU Driver
0004  *
0005  *              GRU HANDLE DEFINITION
0006  *
0007  *  Copyright (c) 2008 Silicon Graphics, Inc.  All Rights Reserved.
0008  */
0009 
0010 #ifndef __GRUHANDLES_H__
0011 #define __GRUHANDLES_H__
0012 #include "gru_instructions.h"
0013 
0014 /*
0015  * Manifest constants for GRU Memory Map
0016  */
0017 #define GRU_GSEG0_BASE      0
0018 #define GRU_MCS_BASE        (64 * 1024 * 1024)
0019 #define GRU_SIZE        (128UL * 1024 * 1024)
0020 
0021 /* Handle & resource counts */
0022 #define GRU_NUM_CB      128
0023 #define GRU_NUM_DSR_BYTES   (32 * 1024)
0024 #define GRU_NUM_TFM     16
0025 #define GRU_NUM_TGH     24
0026 #define GRU_NUM_CBE     128
0027 #define GRU_NUM_TFH     128
0028 #define GRU_NUM_CCH     16
0029 
0030 /* Maximum resource counts that can be reserved by user programs */
0031 #define GRU_NUM_USER_CBR    GRU_NUM_CBE
0032 #define GRU_NUM_USER_DSR_BYTES  GRU_NUM_DSR_BYTES
0033 
0034 /* Bytes per handle & handle stride. Code assumes all cb, tfh, cbe handles
0035  * are the same */
0036 #define GRU_HANDLE_BYTES    64
0037 #define GRU_HANDLE_STRIDE   256
0038 
0039 /* Base addresses of handles */
0040 #define GRU_TFM_BASE        (GRU_MCS_BASE + 0x00000)
0041 #define GRU_TGH_BASE        (GRU_MCS_BASE + 0x08000)
0042 #define GRU_CBE_BASE        (GRU_MCS_BASE + 0x10000)
0043 #define GRU_TFH_BASE        (GRU_MCS_BASE + 0x18000)
0044 #define GRU_CCH_BASE        (GRU_MCS_BASE + 0x20000)
0045 
0046 /* User gseg constants */
0047 #define GRU_GSEG_STRIDE     (4 * 1024 * 1024)
0048 #define GSEG_BASE(a)        ((a) & ~(GRU_GSEG_PAGESIZE - 1))
0049 
0050 /* Data segment constants */
0051 #define GRU_DSR_AU_BYTES    1024
0052 #define GRU_DSR_CL      (GRU_NUM_DSR_BYTES / GRU_CACHE_LINE_BYTES)
0053 #define GRU_DSR_AU_CL       (GRU_DSR_AU_BYTES / GRU_CACHE_LINE_BYTES)
0054 #define GRU_DSR_AU      (GRU_NUM_DSR_BYTES / GRU_DSR_AU_BYTES)
0055 
0056 /* Control block constants */
0057 #define GRU_CBR_AU_SIZE     2
0058 #define GRU_CBR_AU      (GRU_NUM_CBE / GRU_CBR_AU_SIZE)
0059 
0060 /* Convert resource counts to the number of AU */
0061 #define GRU_DS_BYTES_TO_AU(n)   DIV_ROUND_UP(n, GRU_DSR_AU_BYTES)
0062 #define GRU_CB_COUNT_TO_AU(n)   DIV_ROUND_UP(n, GRU_CBR_AU_SIZE)
0063 
0064 /* UV limits */
0065 #define GRU_CHIPLETS_PER_HUB    2
0066 #define GRU_HUBS_PER_BLADE  1
0067 #define GRU_CHIPLETS_PER_BLADE  (GRU_HUBS_PER_BLADE * GRU_CHIPLETS_PER_HUB)
0068 
0069 /* User GRU Gseg offsets */
0070 #define GRU_CB_BASE     0
0071 #define GRU_CB_LIMIT        (GRU_CB_BASE + GRU_HANDLE_STRIDE * GRU_NUM_CBE)
0072 #define GRU_DS_BASE     0x20000
0073 #define GRU_DS_LIMIT        (GRU_DS_BASE + GRU_NUM_DSR_BYTES)
0074 
0075 /* Convert a GRU physical address to the chiplet offset */
0076 #define GSEGPOFF(h)         ((h) & (GRU_SIZE - 1))
0077 
0078 /* Convert an arbitrary handle address to the beginning of the GRU segment */
0079 #define GRUBASE(h)      ((void *)((unsigned long)(h) & ~(GRU_SIZE - 1)))
0080 
0081 /* Test a valid handle address to determine the type */
0082 #define TYPE_IS(hn, h)      ((h) >= GRU_##hn##_BASE && (h) <    \
0083         GRU_##hn##_BASE + GRU_NUM_##hn * GRU_HANDLE_STRIDE &&   \
0084         (((h) & (GRU_HANDLE_STRIDE - 1)) == 0))
0085 
0086 
0087 /* General addressing macros. */
0088 static inline void *get_gseg_base_address(void *base, int ctxnum)
0089 {
0090     return (void *)(base + GRU_GSEG0_BASE + GRU_GSEG_STRIDE * ctxnum);
0091 }
0092 
0093 static inline void *get_gseg_base_address_cb(void *base, int ctxnum, int line)
0094 {
0095     return (void *)(get_gseg_base_address(base, ctxnum) +
0096             GRU_CB_BASE + GRU_HANDLE_STRIDE * line);
0097 }
0098 
0099 static inline void *get_gseg_base_address_ds(void *base, int ctxnum, int line)
0100 {
0101     return (void *)(get_gseg_base_address(base, ctxnum) + GRU_DS_BASE +
0102             GRU_CACHE_LINE_BYTES * line);
0103 }
0104 
0105 static inline struct gru_tlb_fault_map *get_tfm(void *base, int ctxnum)
0106 {
0107     return (struct gru_tlb_fault_map *)(base + GRU_TFM_BASE +
0108                     ctxnum * GRU_HANDLE_STRIDE);
0109 }
0110 
0111 static inline struct gru_tlb_global_handle *get_tgh(void *base, int ctxnum)
0112 {
0113     return (struct gru_tlb_global_handle *)(base + GRU_TGH_BASE +
0114                     ctxnum * GRU_HANDLE_STRIDE);
0115 }
0116 
0117 static inline struct gru_control_block_extended *get_cbe(void *base, int ctxnum)
0118 {
0119     return (struct gru_control_block_extended *)(base + GRU_CBE_BASE +
0120                     ctxnum * GRU_HANDLE_STRIDE);
0121 }
0122 
0123 static inline struct gru_tlb_fault_handle *get_tfh(void *base, int ctxnum)
0124 {
0125     return (struct gru_tlb_fault_handle *)(base + GRU_TFH_BASE +
0126                     ctxnum * GRU_HANDLE_STRIDE);
0127 }
0128 
0129 static inline struct gru_context_configuration_handle *get_cch(void *base,
0130                     int ctxnum)
0131 {
0132     return (struct gru_context_configuration_handle *)(base +
0133                 GRU_CCH_BASE + ctxnum * GRU_HANDLE_STRIDE);
0134 }
0135 
0136 static inline unsigned long get_cb_number(void *cb)
0137 {
0138     return (((unsigned long)cb - GRU_CB_BASE) % GRU_GSEG_PAGESIZE) /
0139                     GRU_HANDLE_STRIDE;
0140 }
0141 
0142 /* byte offset to a specific GRU chiplet. (p=pnode, c=chiplet (0 or 1)*/
0143 static inline unsigned long gru_chiplet_paddr(unsigned long paddr, int pnode,
0144                             int chiplet)
0145 {
0146     return paddr + GRU_SIZE * (2 * pnode  + chiplet);
0147 }
0148 
0149 static inline void *gru_chiplet_vaddr(void *vaddr, int pnode, int chiplet)
0150 {
0151     return vaddr + GRU_SIZE * (2 * pnode  + chiplet);
0152 }
0153 
0154 static inline struct gru_control_block_extended *gru_tfh_to_cbe(
0155                     struct gru_tlb_fault_handle *tfh)
0156 {
0157     unsigned long cbe;
0158 
0159     cbe = (unsigned long)tfh - GRU_TFH_BASE + GRU_CBE_BASE;
0160     return (struct gru_control_block_extended*)cbe;
0161 }
0162 
0163 
0164 
0165 
0166 /*
0167  * Global TLB Fault Map
0168  *  Bitmap of outstanding TLB misses needing interrupt/polling service.
0169  *
0170  */
0171 struct gru_tlb_fault_map {
0172     unsigned long fault_bits[BITS_TO_LONGS(GRU_NUM_CBE)];
0173     unsigned long fill0[2];
0174     unsigned long done_bits[BITS_TO_LONGS(GRU_NUM_CBE)];
0175     unsigned long fill1[2];
0176 };
0177 
0178 /*
0179  * TGH - TLB Global Handle
0180  *  Used for TLB flushing.
0181  *
0182  */
0183 struct gru_tlb_global_handle {
0184     unsigned int cmd:1;     /* DW 0 */
0185     unsigned int delresp:1;
0186     unsigned int opc:1;
0187     unsigned int fill1:5;
0188 
0189     unsigned int fill2:8;
0190 
0191     unsigned int status:2;
0192     unsigned long fill3:2;
0193     unsigned int state:3;
0194     unsigned long fill4:1;
0195 
0196     unsigned int cause:3;
0197     unsigned long fill5:37;
0198 
0199     unsigned long vaddr:64;     /* DW 1 */
0200 
0201     unsigned int asid:24;       /* DW 2 */
0202     unsigned int fill6:8;
0203 
0204     unsigned int pagesize:5;
0205     unsigned int fill7:11;
0206 
0207     unsigned int global:1;
0208     unsigned int fill8:15;
0209 
0210     unsigned long vaddrmask:39; /* DW 3 */
0211     unsigned int fill9:9;
0212     unsigned int n:10;
0213     unsigned int fill10:6;
0214 
0215     unsigned int ctxbitmap:16;  /* DW4 */
0216     unsigned long fill11[3];
0217 };
0218 
0219 enum gru_tgh_cmd {
0220     TGHCMD_START
0221 };
0222 
0223 enum gru_tgh_opc {
0224     TGHOP_TLBNOP,
0225     TGHOP_TLBINV
0226 };
0227 
0228 enum gru_tgh_status {
0229     TGHSTATUS_IDLE,
0230     TGHSTATUS_EXCEPTION,
0231     TGHSTATUS_ACTIVE
0232 };
0233 
0234 enum gru_tgh_state {
0235     TGHSTATE_IDLE,
0236     TGHSTATE_PE_INVAL,
0237     TGHSTATE_INTERRUPT_INVAL,
0238     TGHSTATE_WAITDONE,
0239     TGHSTATE_RESTART_CTX,
0240 };
0241 
0242 enum gru_tgh_cause {
0243     TGHCAUSE_RR_ECC,
0244     TGHCAUSE_TLB_ECC,
0245     TGHCAUSE_LRU_ECC,
0246     TGHCAUSE_PS_ECC,
0247     TGHCAUSE_MUL_ERR,
0248     TGHCAUSE_DATA_ERR,
0249     TGHCAUSE_SW_FORCE
0250 };
0251 
0252 
0253 /*
0254  * TFH - TLB Global Handle
0255  *  Used for TLB dropins into the GRU TLB.
0256  *
0257  */
0258 struct gru_tlb_fault_handle {
0259     unsigned int cmd:1;     /* DW 0 - low 32*/
0260     unsigned int delresp:1;
0261     unsigned int fill0:2;
0262     unsigned int opc:3;
0263     unsigned int fill1:9;
0264 
0265     unsigned int status:2;
0266     unsigned int fill2:2;
0267     unsigned int state:3;
0268     unsigned int fill3:1;
0269 
0270     unsigned int cause:6;
0271     unsigned int cb_int:1;
0272     unsigned int fill4:1;
0273 
0274     unsigned int indexway:12;   /* DW 0 - high 32 */
0275     unsigned int fill5:4;
0276 
0277     unsigned int ctxnum:4;
0278     unsigned int fill6:12;
0279 
0280     unsigned long missvaddr:64; /* DW 1 */
0281 
0282     unsigned int missasid:24;   /* DW 2 */
0283     unsigned int fill7:8;
0284     unsigned int fillasid:24;
0285     unsigned int dirty:1;
0286     unsigned int gaa:2;
0287     unsigned long fill8:5;
0288 
0289     unsigned long pfn:41;       /* DW 3 */
0290     unsigned int fill9:7;
0291     unsigned int pagesize:5;
0292     unsigned int fill10:11;
0293 
0294     unsigned long fillvaddr:64; /* DW 4 */
0295 
0296     unsigned long fill11[3];
0297 };
0298 
0299 enum gru_tfh_opc {
0300     TFHOP_NOOP,
0301     TFHOP_RESTART,
0302     TFHOP_WRITE_ONLY,
0303     TFHOP_WRITE_RESTART,
0304     TFHOP_EXCEPTION,
0305     TFHOP_USER_POLLING_MODE = 7,
0306 };
0307 
0308 enum tfh_status {
0309     TFHSTATUS_IDLE,
0310     TFHSTATUS_EXCEPTION,
0311     TFHSTATUS_ACTIVE,
0312 };
0313 
0314 enum tfh_state {
0315     TFHSTATE_INACTIVE,
0316     TFHSTATE_IDLE,
0317     TFHSTATE_MISS_UPM,
0318     TFHSTATE_MISS_FMM,
0319     TFHSTATE_HW_ERR,
0320     TFHSTATE_WRITE_TLB,
0321     TFHSTATE_RESTART_CBR,
0322 };
0323 
0324 /* TFH cause bits */
0325 enum tfh_cause {
0326     TFHCAUSE_NONE,
0327     TFHCAUSE_TLB_MISS,
0328     TFHCAUSE_TLB_MOD,
0329     TFHCAUSE_HW_ERROR_RR,
0330     TFHCAUSE_HW_ERROR_MAIN_ARRAY,
0331     TFHCAUSE_HW_ERROR_VALID,
0332     TFHCAUSE_HW_ERROR_PAGESIZE,
0333     TFHCAUSE_INSTRUCTION_EXCEPTION,
0334     TFHCAUSE_UNCORRECTIBLE_ERROR,
0335 };
0336 
0337 /* GAA values */
0338 #define GAA_RAM             0x0
0339 #define GAA_NCRAM           0x2
0340 #define GAA_MMIO            0x1
0341 #define GAA_REGISTER            0x3
0342 
0343 /* GRU paddr shift for pfn. (NOTE: shift is NOT by actual pagesize) */
0344 #define GRU_PADDR_SHIFT         12
0345 
0346 /*
0347  * Context Configuration handle
0348  *  Used to allocate resources to a GSEG context.
0349  *
0350  */
0351 struct gru_context_configuration_handle {
0352     unsigned int cmd:1;         /* DW0 */
0353     unsigned int delresp:1;
0354     unsigned int opc:3;
0355     unsigned int unmap_enable:1;
0356     unsigned int req_slice_set_enable:1;
0357     unsigned int req_slice:2;
0358     unsigned int cb_int_enable:1;
0359     unsigned int tlb_int_enable:1;
0360     unsigned int tfm_fault_bit_enable:1;
0361     unsigned int tlb_int_select:4;
0362 
0363     unsigned int status:2;
0364     unsigned int state:2;
0365     unsigned int reserved2:4;
0366 
0367     unsigned int cause:4;
0368     unsigned int tfm_done_bit_enable:1;
0369     unsigned int unused:3;
0370 
0371     unsigned int dsr_allocation_map;
0372 
0373     unsigned long cbr_allocation_map;   /* DW1 */
0374 
0375     unsigned int asid[8];           /* DW 2 - 5 */
0376     unsigned short sizeavail[8];        /* DW 6 - 7 */
0377 } __attribute__ ((packed));
0378 
0379 enum gru_cch_opc {
0380     CCHOP_START = 1,
0381     CCHOP_ALLOCATE,
0382     CCHOP_INTERRUPT,
0383     CCHOP_DEALLOCATE,
0384     CCHOP_INTERRUPT_SYNC,
0385 };
0386 
0387 enum gru_cch_status {
0388     CCHSTATUS_IDLE,
0389     CCHSTATUS_EXCEPTION,
0390     CCHSTATUS_ACTIVE,
0391 };
0392 
0393 enum gru_cch_state {
0394     CCHSTATE_INACTIVE,
0395     CCHSTATE_MAPPED,
0396     CCHSTATE_ACTIVE,
0397     CCHSTATE_INTERRUPTED,
0398 };
0399 
0400 /* CCH Exception cause */
0401 enum gru_cch_cause {
0402     CCHCAUSE_REGION_REGISTER_WRITE_ERROR = 1,
0403     CCHCAUSE_ILLEGAL_OPCODE = 2,
0404     CCHCAUSE_INVALID_START_REQUEST = 3,
0405     CCHCAUSE_INVALID_ALLOCATION_REQUEST = 4,
0406     CCHCAUSE_INVALID_DEALLOCATION_REQUEST = 5,
0407     CCHCAUSE_INVALID_INTERRUPT_REQUEST = 6,
0408     CCHCAUSE_CCH_BUSY = 7,
0409     CCHCAUSE_NO_CBRS_TO_ALLOCATE = 8,
0410     CCHCAUSE_BAD_TFM_CONFIG = 9,
0411     CCHCAUSE_CBR_RESOURCES_OVERSUBSCRIPED = 10,
0412     CCHCAUSE_DSR_RESOURCES_OVERSUBSCRIPED = 11,
0413     CCHCAUSE_CBR_DEALLOCATION_ERROR = 12,
0414 };
0415 /*
0416  * CBE - Control Block Extended
0417  *  Maintains internal GRU state for active CBs.
0418  *
0419  */
0420 struct gru_control_block_extended {
0421     unsigned int reserved0:1;   /* DW 0  - low */
0422     unsigned int imacpy:3;
0423     unsigned int reserved1:4;
0424     unsigned int xtypecpy:3;
0425     unsigned int iaa0cpy:2;
0426     unsigned int iaa1cpy:2;
0427     unsigned int reserved2:1;
0428     unsigned int opccpy:8;
0429     unsigned int exopccpy:8;
0430 
0431     unsigned int idef2cpy:22;   /* DW 0  - high */
0432     unsigned int reserved3:10;
0433 
0434     unsigned int idef4cpy:22;   /* DW 1 */
0435     unsigned int reserved4:10;
0436     unsigned int idef4upd:22;
0437     unsigned int reserved5:10;
0438 
0439     unsigned long idef1upd:64;  /* DW 2 */
0440 
0441     unsigned long idef5cpy:64;  /* DW 3 */
0442 
0443     unsigned long idef6cpy:64;  /* DW 4 */
0444 
0445     unsigned long idef3upd:64;  /* DW 5 */
0446 
0447     unsigned long idef5upd:64;  /* DW 6 */
0448 
0449     unsigned int idef2upd:22;   /* DW 7 */
0450     unsigned int reserved6:10;
0451 
0452     unsigned int ecause:20;
0453     unsigned int cbrstate:4;
0454     unsigned int cbrexecstatus:8;
0455 };
0456 
0457 /* CBE fields for active BCOPY instructions */
0458 #define cbe_baddr0  idef1upd
0459 #define cbe_baddr1  idef3upd
0460 #define cbe_src_cl  idef6cpy
0461 #define cbe_nelemcur    idef5upd
0462 
0463 enum gru_cbr_state {
0464     CBRSTATE_INACTIVE,
0465     CBRSTATE_IDLE,
0466     CBRSTATE_PE_CHECK,
0467     CBRSTATE_QUEUED,
0468     CBRSTATE_WAIT_RESPONSE,
0469     CBRSTATE_INTERRUPTED,
0470     CBRSTATE_INTERRUPTED_MISS_FMM,
0471     CBRSTATE_BUSY_INTERRUPT_MISS_FMM,
0472     CBRSTATE_INTERRUPTED_MISS_UPM,
0473     CBRSTATE_BUSY_INTERRUPTED_MISS_UPM,
0474     CBRSTATE_REQUEST_ISSUE,
0475     CBRSTATE_BUSY_INTERRUPT,
0476 };
0477 
0478 /* CBE cbrexecstatus bits  - defined in gru_instructions.h*/
0479 /* CBE ecause bits  - defined in gru_instructions.h */
0480 
0481 /*
0482  * Convert a processor pagesize into the strange encoded pagesize used by the
0483  * GRU. Processor pagesize is encoded as log of bytes per page. (or PAGE_SHIFT)
0484  *  pagesize    log pagesize    grupagesize
0485  *    4k            12  0
0486  *   16k            14  1
0487  *   64k            16  2
0488  *  256k            18  3
0489  *    1m            20  4
0490  *    2m            21  5
0491  *    4m            22  6
0492  *   16m            24  7
0493  *   64m            26  8
0494  *  ...
0495  */
0496 #define GRU_PAGESIZE(sh)    ((((sh) > 20 ? (sh) + 2 : (sh)) >> 1) - 6)
0497 #define GRU_SIZEAVAIL(sh)   (1UL << GRU_PAGESIZE(sh))
0498 
0499 /* minimum TLB purge count to ensure a full purge */
0500 #define GRUMAXINVAL     1024UL
0501 
0502 int cch_allocate(struct gru_context_configuration_handle *cch);
0503 int cch_start(struct gru_context_configuration_handle *cch);
0504 int cch_interrupt(struct gru_context_configuration_handle *cch);
0505 int cch_deallocate(struct gru_context_configuration_handle *cch);
0506 int cch_interrupt_sync(struct gru_context_configuration_handle *cch);
0507 int tgh_invalidate(struct gru_tlb_global_handle *tgh, unsigned long vaddr,
0508     unsigned long vaddrmask, int asid, int pagesize, int global, int n,
0509     unsigned short ctxbitmap);
0510 int tfh_write_only(struct gru_tlb_fault_handle *tfh, unsigned long paddr,
0511     int gaa, unsigned long vaddr, int asid, int dirty, int pagesize);
0512 void tfh_write_restart(struct gru_tlb_fault_handle *tfh, unsigned long paddr,
0513     int gaa, unsigned long vaddr, int asid, int dirty, int pagesize);
0514 void tfh_user_polling_mode(struct gru_tlb_fault_handle *tfh);
0515 void tfh_exception(struct gru_tlb_fault_handle *tfh);
0516 
0517 #endif /* __GRUHANDLES_H__ */