11a59d1b8SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
234d8a380SJack Steiner /*
334d8a380SJack Steiner * SN Platform GRU Driver
434d8a380SJack Steiner *
534d8a380SJack Steiner * GRU HANDLE DEFINITION
634d8a380SJack Steiner *
734d8a380SJack Steiner * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
834d8a380SJack Steiner */
934d8a380SJack Steiner
1034d8a380SJack Steiner #ifndef __GRUHANDLES_H__
1134d8a380SJack Steiner #define __GRUHANDLES_H__
1234d8a380SJack Steiner #include "gru_instructions.h"
1334d8a380SJack Steiner
1434d8a380SJack Steiner /*
1534d8a380SJack Steiner * Manifest constants for GRU Memory Map
1634d8a380SJack Steiner */
1734d8a380SJack Steiner #define GRU_GSEG0_BASE 0
1834d8a380SJack Steiner #define GRU_MCS_BASE (64 * 1024 * 1024)
1934d8a380SJack Steiner #define GRU_SIZE (128UL * 1024 * 1024)
2034d8a380SJack Steiner
2134d8a380SJack Steiner /* Handle & resource counts */
2234d8a380SJack Steiner #define GRU_NUM_CB 128
2334d8a380SJack Steiner #define GRU_NUM_DSR_BYTES (32 * 1024)
2434d8a380SJack Steiner #define GRU_NUM_TFM 16
2534d8a380SJack Steiner #define GRU_NUM_TGH 24
2634d8a380SJack Steiner #define GRU_NUM_CBE 128
2734d8a380SJack Steiner #define GRU_NUM_TFH 128
2834d8a380SJack Steiner #define GRU_NUM_CCH 16
2934d8a380SJack Steiner
3034d8a380SJack Steiner /* Maximum resource counts that can be reserved by user programs */
3134d8a380SJack Steiner #define GRU_NUM_USER_CBR GRU_NUM_CBE
3234d8a380SJack Steiner #define GRU_NUM_USER_DSR_BYTES GRU_NUM_DSR_BYTES
3334d8a380SJack Steiner
3434d8a380SJack Steiner /* Bytes per handle & handle stride. Code assumes all cb, tfh, cbe handles
3534d8a380SJack Steiner * are the same */
3634d8a380SJack Steiner #define GRU_HANDLE_BYTES 64
3734d8a380SJack Steiner #define GRU_HANDLE_STRIDE 256
3834d8a380SJack Steiner
3934d8a380SJack Steiner /* Base addresses of handles */
4034d8a380SJack Steiner #define GRU_TFM_BASE (GRU_MCS_BASE + 0x00000)
4134d8a380SJack Steiner #define GRU_TGH_BASE (GRU_MCS_BASE + 0x08000)
4234d8a380SJack Steiner #define GRU_CBE_BASE (GRU_MCS_BASE + 0x10000)
4334d8a380SJack Steiner #define GRU_TFH_BASE (GRU_MCS_BASE + 0x18000)
4434d8a380SJack Steiner #define GRU_CCH_BASE (GRU_MCS_BASE + 0x20000)
4534d8a380SJack Steiner
4634d8a380SJack Steiner /* User gseg constants */
4734d8a380SJack Steiner #define GRU_GSEG_STRIDE (4 * 1024 * 1024)
4834d8a380SJack Steiner #define GSEG_BASE(a) ((a) & ~(GRU_GSEG_PAGESIZE - 1))
4934d8a380SJack Steiner
5034d8a380SJack Steiner /* Data segment constants */
5134d8a380SJack Steiner #define GRU_DSR_AU_BYTES 1024
5234d8a380SJack Steiner #define GRU_DSR_CL (GRU_NUM_DSR_BYTES / GRU_CACHE_LINE_BYTES)
5334d8a380SJack Steiner #define GRU_DSR_AU_CL (GRU_DSR_AU_BYTES / GRU_CACHE_LINE_BYTES)
5434d8a380SJack Steiner #define GRU_DSR_AU (GRU_NUM_DSR_BYTES / GRU_DSR_AU_BYTES)
5534d8a380SJack Steiner
5634d8a380SJack Steiner /* Control block constants */
5734d8a380SJack Steiner #define GRU_CBR_AU_SIZE 2
5834d8a380SJack Steiner #define GRU_CBR_AU (GRU_NUM_CBE / GRU_CBR_AU_SIZE)
5934d8a380SJack Steiner
6034d8a380SJack Steiner /* Convert resource counts to the number of AU */
6134d8a380SJack Steiner #define GRU_DS_BYTES_TO_AU(n) DIV_ROUND_UP(n, GRU_DSR_AU_BYTES)
6234d8a380SJack Steiner #define GRU_CB_COUNT_TO_AU(n) DIV_ROUND_UP(n, GRU_CBR_AU_SIZE)
6334d8a380SJack Steiner
6434d8a380SJack Steiner /* UV limits */
6534d8a380SJack Steiner #define GRU_CHIPLETS_PER_HUB 2
6634d8a380SJack Steiner #define GRU_HUBS_PER_BLADE 1
6734d8a380SJack Steiner #define GRU_CHIPLETS_PER_BLADE (GRU_HUBS_PER_BLADE * GRU_CHIPLETS_PER_HUB)
6834d8a380SJack Steiner
6934d8a380SJack Steiner /* User GRU Gseg offsets */
7034d8a380SJack Steiner #define GRU_CB_BASE 0
7134d8a380SJack Steiner #define GRU_CB_LIMIT (GRU_CB_BASE + GRU_HANDLE_STRIDE * GRU_NUM_CBE)
7234d8a380SJack Steiner #define GRU_DS_BASE 0x20000
7334d8a380SJack Steiner #define GRU_DS_LIMIT (GRU_DS_BASE + GRU_NUM_DSR_BYTES)
7434d8a380SJack Steiner
7534d8a380SJack Steiner /* Convert a GRU physical address to the chiplet offset */
7634d8a380SJack Steiner #define GSEGPOFF(h) ((h) & (GRU_SIZE - 1))
7734d8a380SJack Steiner
7834d8a380SJack Steiner /* Convert an arbitrary handle address to the beginning of the GRU segment */
7934d8a380SJack Steiner #define GRUBASE(h) ((void *)((unsigned long)(h) & ~(GRU_SIZE - 1)))
8034d8a380SJack Steiner
81648eb8e5SJack Steiner /* Test a valid handle address to determine the type */
82648eb8e5SJack Steiner #define TYPE_IS(hn, h) ((h) >= GRU_##hn##_BASE && (h) < \
83648eb8e5SJack Steiner GRU_##hn##_BASE + GRU_NUM_##hn * GRU_HANDLE_STRIDE && \
84648eb8e5SJack Steiner (((h) & (GRU_HANDLE_STRIDE - 1)) == 0))
85648eb8e5SJack Steiner
86648eb8e5SJack Steiner
8734d8a380SJack Steiner /* General addressing macros. */
get_gseg_base_address(void * base,int ctxnum)8834d8a380SJack Steiner static inline void *get_gseg_base_address(void *base, int ctxnum)
8934d8a380SJack Steiner {
9034d8a380SJack Steiner return (void *)(base + GRU_GSEG0_BASE + GRU_GSEG_STRIDE * ctxnum);
9134d8a380SJack Steiner }
9234d8a380SJack Steiner
get_gseg_base_address_cb(void * base,int ctxnum,int line)9334d8a380SJack Steiner static inline void *get_gseg_base_address_cb(void *base, int ctxnum, int line)
9434d8a380SJack Steiner {
9534d8a380SJack Steiner return (void *)(get_gseg_base_address(base, ctxnum) +
9634d8a380SJack Steiner GRU_CB_BASE + GRU_HANDLE_STRIDE * line);
9734d8a380SJack Steiner }
9834d8a380SJack Steiner
get_gseg_base_address_ds(void * base,int ctxnum,int line)9934d8a380SJack Steiner static inline void *get_gseg_base_address_ds(void *base, int ctxnum, int line)
10034d8a380SJack Steiner {
10134d8a380SJack Steiner return (void *)(get_gseg_base_address(base, ctxnum) + GRU_DS_BASE +
10234d8a380SJack Steiner GRU_CACHE_LINE_BYTES * line);
10334d8a380SJack Steiner }
10434d8a380SJack Steiner
get_tfm(void * base,int ctxnum)10534d8a380SJack Steiner static inline struct gru_tlb_fault_map *get_tfm(void *base, int ctxnum)
10634d8a380SJack Steiner {
10734d8a380SJack Steiner return (struct gru_tlb_fault_map *)(base + GRU_TFM_BASE +
10834d8a380SJack Steiner ctxnum * GRU_HANDLE_STRIDE);
10934d8a380SJack Steiner }
11034d8a380SJack Steiner
get_tgh(void * base,int ctxnum)11134d8a380SJack Steiner static inline struct gru_tlb_global_handle *get_tgh(void *base, int ctxnum)
11234d8a380SJack Steiner {
11334d8a380SJack Steiner return (struct gru_tlb_global_handle *)(base + GRU_TGH_BASE +
11434d8a380SJack Steiner ctxnum * GRU_HANDLE_STRIDE);
11534d8a380SJack Steiner }
11634d8a380SJack Steiner
get_cbe(void * base,int ctxnum)11734d8a380SJack Steiner static inline struct gru_control_block_extended *get_cbe(void *base, int ctxnum)
11834d8a380SJack Steiner {
11934d8a380SJack Steiner return (struct gru_control_block_extended *)(base + GRU_CBE_BASE +
12034d8a380SJack Steiner ctxnum * GRU_HANDLE_STRIDE);
12134d8a380SJack Steiner }
12234d8a380SJack Steiner
get_tfh(void * base,int ctxnum)12334d8a380SJack Steiner static inline struct gru_tlb_fault_handle *get_tfh(void *base, int ctxnum)
12434d8a380SJack Steiner {
12534d8a380SJack Steiner return (struct gru_tlb_fault_handle *)(base + GRU_TFH_BASE +
12634d8a380SJack Steiner ctxnum * GRU_HANDLE_STRIDE);
12734d8a380SJack Steiner }
12834d8a380SJack Steiner
get_cch(void * base,int ctxnum)12934d8a380SJack Steiner static inline struct gru_context_configuration_handle *get_cch(void *base,
13034d8a380SJack Steiner int ctxnum)
13134d8a380SJack Steiner {
13234d8a380SJack Steiner return (struct gru_context_configuration_handle *)(base +
13334d8a380SJack Steiner GRU_CCH_BASE + ctxnum * GRU_HANDLE_STRIDE);
13434d8a380SJack Steiner }
13534d8a380SJack Steiner
get_cb_number(void * cb)13634d8a380SJack Steiner static inline unsigned long get_cb_number(void *cb)
13734d8a380SJack Steiner {
13834d8a380SJack Steiner return (((unsigned long)cb - GRU_CB_BASE) % GRU_GSEG_PAGESIZE) /
13934d8a380SJack Steiner GRU_HANDLE_STRIDE;
14034d8a380SJack Steiner }
14134d8a380SJack Steiner
14234d8a380SJack Steiner /* byte offset to a specific GRU chiplet. (p=pnode, c=chiplet (0 or 1)*/
gru_chiplet_paddr(unsigned long paddr,int pnode,int chiplet)14334d8a380SJack Steiner static inline unsigned long gru_chiplet_paddr(unsigned long paddr, int pnode,
14434d8a380SJack Steiner int chiplet)
14534d8a380SJack Steiner {
14634d8a380SJack Steiner return paddr + GRU_SIZE * (2 * pnode + chiplet);
14734d8a380SJack Steiner }
14834d8a380SJack Steiner
gru_chiplet_vaddr(void * vaddr,int pnode,int chiplet)14934d8a380SJack Steiner static inline void *gru_chiplet_vaddr(void *vaddr, int pnode, int chiplet)
15034d8a380SJack Steiner {
15134d8a380SJack Steiner return vaddr + GRU_SIZE * (2 * pnode + chiplet);
15234d8a380SJack Steiner }
15334d8a380SJack Steiner
gru_tfh_to_cbe(struct gru_tlb_fault_handle * tfh)154c550222fSJack Steiner static inline struct gru_control_block_extended *gru_tfh_to_cbe(
155c550222fSJack Steiner struct gru_tlb_fault_handle *tfh)
156c550222fSJack Steiner {
157c550222fSJack Steiner unsigned long cbe;
158c550222fSJack Steiner
159c550222fSJack Steiner cbe = (unsigned long)tfh - GRU_TFH_BASE + GRU_CBE_BASE;
160c550222fSJack Steiner return (struct gru_control_block_extended*)cbe;
161c550222fSJack Steiner }
162c550222fSJack Steiner
163c550222fSJack Steiner
16434d8a380SJack Steiner
16534d8a380SJack Steiner
16634d8a380SJack Steiner /*
16734d8a380SJack Steiner * Global TLB Fault Map
16834d8a380SJack Steiner * Bitmap of outstanding TLB misses needing interrupt/polling service.
16934d8a380SJack Steiner *
17034d8a380SJack Steiner */
17134d8a380SJack Steiner struct gru_tlb_fault_map {
17234d8a380SJack Steiner unsigned long fault_bits[BITS_TO_LONGS(GRU_NUM_CBE)];
17334d8a380SJack Steiner unsigned long fill0[2];
17434d8a380SJack Steiner unsigned long done_bits[BITS_TO_LONGS(GRU_NUM_CBE)];
17534d8a380SJack Steiner unsigned long fill1[2];
17634d8a380SJack Steiner };
17734d8a380SJack Steiner
17834d8a380SJack Steiner /*
17934d8a380SJack Steiner * TGH - TLB Global Handle
18034d8a380SJack Steiner * Used for TLB flushing.
18134d8a380SJack Steiner *
18234d8a380SJack Steiner */
18334d8a380SJack Steiner struct gru_tlb_global_handle {
18434d8a380SJack Steiner unsigned int cmd:1; /* DW 0 */
18534d8a380SJack Steiner unsigned int delresp:1;
18634d8a380SJack Steiner unsigned int opc:1;
18734d8a380SJack Steiner unsigned int fill1:5;
18834d8a380SJack Steiner
18934d8a380SJack Steiner unsigned int fill2:8;
19034d8a380SJack Steiner
19134d8a380SJack Steiner unsigned int status:2;
19234d8a380SJack Steiner unsigned long fill3:2;
19334d8a380SJack Steiner unsigned int state:3;
19434d8a380SJack Steiner unsigned long fill4:1;
19534d8a380SJack Steiner
19634d8a380SJack Steiner unsigned int cause:3;
19734d8a380SJack Steiner unsigned long fill5:37;
19834d8a380SJack Steiner
19934d8a380SJack Steiner unsigned long vaddr:64; /* DW 1 */
20034d8a380SJack Steiner
20134d8a380SJack Steiner unsigned int asid:24; /* DW 2 */
20234d8a380SJack Steiner unsigned int fill6:8;
20334d8a380SJack Steiner
20434d8a380SJack Steiner unsigned int pagesize:5;
20534d8a380SJack Steiner unsigned int fill7:11;
20634d8a380SJack Steiner
20734d8a380SJack Steiner unsigned int global:1;
20834d8a380SJack Steiner unsigned int fill8:15;
20934d8a380SJack Steiner
21034d8a380SJack Steiner unsigned long vaddrmask:39; /* DW 3 */
21134d8a380SJack Steiner unsigned int fill9:9;
21234d8a380SJack Steiner unsigned int n:10;
21334d8a380SJack Steiner unsigned int fill10:6;
21434d8a380SJack Steiner
21534d8a380SJack Steiner unsigned int ctxbitmap:16; /* DW4 */
21634d8a380SJack Steiner unsigned long fill11[3];
21734d8a380SJack Steiner };
21834d8a380SJack Steiner
21934d8a380SJack Steiner enum gru_tgh_cmd {
22034d8a380SJack Steiner TGHCMD_START
22134d8a380SJack Steiner };
22234d8a380SJack Steiner
22334d8a380SJack Steiner enum gru_tgh_opc {
22434d8a380SJack Steiner TGHOP_TLBNOP,
22534d8a380SJack Steiner TGHOP_TLBINV
22634d8a380SJack Steiner };
22734d8a380SJack Steiner
22834d8a380SJack Steiner enum gru_tgh_status {
22934d8a380SJack Steiner TGHSTATUS_IDLE,
23034d8a380SJack Steiner TGHSTATUS_EXCEPTION,
23134d8a380SJack Steiner TGHSTATUS_ACTIVE
23234d8a380SJack Steiner };
23334d8a380SJack Steiner
23434d8a380SJack Steiner enum gru_tgh_state {
23534d8a380SJack Steiner TGHSTATE_IDLE,
23634d8a380SJack Steiner TGHSTATE_PE_INVAL,
23734d8a380SJack Steiner TGHSTATE_INTERRUPT_INVAL,
23834d8a380SJack Steiner TGHSTATE_WAITDONE,
23934d8a380SJack Steiner TGHSTATE_RESTART_CTX,
24034d8a380SJack Steiner };
24134d8a380SJack Steiner
2425658366aSJack Steiner enum gru_tgh_cause {
2435658366aSJack Steiner TGHCAUSE_RR_ECC,
2445658366aSJack Steiner TGHCAUSE_TLB_ECC,
2455658366aSJack Steiner TGHCAUSE_LRU_ECC,
2465658366aSJack Steiner TGHCAUSE_PS_ECC,
2475658366aSJack Steiner TGHCAUSE_MUL_ERR,
2485658366aSJack Steiner TGHCAUSE_DATA_ERR,
2495658366aSJack Steiner TGHCAUSE_SW_FORCE
2505658366aSJack Steiner };
2515658366aSJack Steiner
2525658366aSJack Steiner
25334d8a380SJack Steiner /*
25434d8a380SJack Steiner * TFH - TLB Global Handle
25534d8a380SJack Steiner * Used for TLB dropins into the GRU TLB.
25634d8a380SJack Steiner *
25734d8a380SJack Steiner */
25834d8a380SJack Steiner struct gru_tlb_fault_handle {
25934d8a380SJack Steiner unsigned int cmd:1; /* DW 0 - low 32*/
26034d8a380SJack Steiner unsigned int delresp:1;
26134d8a380SJack Steiner unsigned int fill0:2;
26234d8a380SJack Steiner unsigned int opc:3;
26334d8a380SJack Steiner unsigned int fill1:9;
26434d8a380SJack Steiner
26534d8a380SJack Steiner unsigned int status:2;
266cd1334f0SJack Steiner unsigned int fill2:2;
26734d8a380SJack Steiner unsigned int state:3;
26834d8a380SJack Steiner unsigned int fill3:1;
26934d8a380SJack Steiner
270270952a9SJack Steiner unsigned int cause:6;
271270952a9SJack Steiner unsigned int cb_int:1;
27234d8a380SJack Steiner unsigned int fill4:1;
27334d8a380SJack Steiner
274cd1334f0SJack Steiner unsigned int indexway:12; /* DW 0 - high 32 */
27534d8a380SJack Steiner unsigned int fill5:4;
27634d8a380SJack Steiner
27734d8a380SJack Steiner unsigned int ctxnum:4;
27834d8a380SJack Steiner unsigned int fill6:12;
27934d8a380SJack Steiner
28034d8a380SJack Steiner unsigned long missvaddr:64; /* DW 1 */
28134d8a380SJack Steiner
28234d8a380SJack Steiner unsigned int missasid:24; /* DW 2 */
28334d8a380SJack Steiner unsigned int fill7:8;
28434d8a380SJack Steiner unsigned int fillasid:24;
28534d8a380SJack Steiner unsigned int dirty:1;
28634d8a380SJack Steiner unsigned int gaa:2;
28734d8a380SJack Steiner unsigned long fill8:5;
28834d8a380SJack Steiner
28934d8a380SJack Steiner unsigned long pfn:41; /* DW 3 */
29034d8a380SJack Steiner unsigned int fill9:7;
29134d8a380SJack Steiner unsigned int pagesize:5;
29234d8a380SJack Steiner unsigned int fill10:11;
29334d8a380SJack Steiner
29434d8a380SJack Steiner unsigned long fillvaddr:64; /* DW 4 */
29534d8a380SJack Steiner
29634d8a380SJack Steiner unsigned long fill11[3];
29734d8a380SJack Steiner };
29834d8a380SJack Steiner
29934d8a380SJack Steiner enum gru_tfh_opc {
30034d8a380SJack Steiner TFHOP_NOOP,
30134d8a380SJack Steiner TFHOP_RESTART,
30234d8a380SJack Steiner TFHOP_WRITE_ONLY,
30334d8a380SJack Steiner TFHOP_WRITE_RESTART,
30434d8a380SJack Steiner TFHOP_EXCEPTION,
30534d8a380SJack Steiner TFHOP_USER_POLLING_MODE = 7,
30634d8a380SJack Steiner };
30734d8a380SJack Steiner
30834d8a380SJack Steiner enum tfh_status {
30934d8a380SJack Steiner TFHSTATUS_IDLE,
31034d8a380SJack Steiner TFHSTATUS_EXCEPTION,
31134d8a380SJack Steiner TFHSTATUS_ACTIVE,
31234d8a380SJack Steiner };
31334d8a380SJack Steiner
31434d8a380SJack Steiner enum tfh_state {
31534d8a380SJack Steiner TFHSTATE_INACTIVE,
31634d8a380SJack Steiner TFHSTATE_IDLE,
31734d8a380SJack Steiner TFHSTATE_MISS_UPM,
31834d8a380SJack Steiner TFHSTATE_MISS_FMM,
31934d8a380SJack Steiner TFHSTATE_HW_ERR,
32034d8a380SJack Steiner TFHSTATE_WRITE_TLB,
32134d8a380SJack Steiner TFHSTATE_RESTART_CBR,
32234d8a380SJack Steiner };
32334d8a380SJack Steiner
32434d8a380SJack Steiner /* TFH cause bits */
32534d8a380SJack Steiner enum tfh_cause {
32634d8a380SJack Steiner TFHCAUSE_NONE,
32734d8a380SJack Steiner TFHCAUSE_TLB_MISS,
32834d8a380SJack Steiner TFHCAUSE_TLB_MOD,
32934d8a380SJack Steiner TFHCAUSE_HW_ERROR_RR,
33034d8a380SJack Steiner TFHCAUSE_HW_ERROR_MAIN_ARRAY,
33134d8a380SJack Steiner TFHCAUSE_HW_ERROR_VALID,
33234d8a380SJack Steiner TFHCAUSE_HW_ERROR_PAGESIZE,
33334d8a380SJack Steiner TFHCAUSE_INSTRUCTION_EXCEPTION,
33434d8a380SJack Steiner TFHCAUSE_UNCORRECTIBLE_ERROR,
33534d8a380SJack Steiner };
33634d8a380SJack Steiner
33734d8a380SJack Steiner /* GAA values */
33834d8a380SJack Steiner #define GAA_RAM 0x0
33934d8a380SJack Steiner #define GAA_NCRAM 0x2
34034d8a380SJack Steiner #define GAA_MMIO 0x1
34134d8a380SJack Steiner #define GAA_REGISTER 0x3
34234d8a380SJack Steiner
34334d8a380SJack Steiner /* GRU paddr shift for pfn. (NOTE: shift is NOT by actual pagesize) */
34434d8a380SJack Steiner #define GRU_PADDR_SHIFT 12
34534d8a380SJack Steiner
34634d8a380SJack Steiner /*
34734d8a380SJack Steiner * Context Configuration handle
34834d8a380SJack Steiner * Used to allocate resources to a GSEG context.
34934d8a380SJack Steiner *
35034d8a380SJack Steiner */
35134d8a380SJack Steiner struct gru_context_configuration_handle {
35234d8a380SJack Steiner unsigned int cmd:1; /* DW0 */
35334d8a380SJack Steiner unsigned int delresp:1;
35434d8a380SJack Steiner unsigned int opc:3;
35534d8a380SJack Steiner unsigned int unmap_enable:1;
35634d8a380SJack Steiner unsigned int req_slice_set_enable:1;
35734d8a380SJack Steiner unsigned int req_slice:2;
35834d8a380SJack Steiner unsigned int cb_int_enable:1;
35934d8a380SJack Steiner unsigned int tlb_int_enable:1;
36034d8a380SJack Steiner unsigned int tfm_fault_bit_enable:1;
36134d8a380SJack Steiner unsigned int tlb_int_select:4;
36234d8a380SJack Steiner
36334d8a380SJack Steiner unsigned int status:2;
36434d8a380SJack Steiner unsigned int state:2;
36534d8a380SJack Steiner unsigned int reserved2:4;
36634d8a380SJack Steiner
36734d8a380SJack Steiner unsigned int cause:4;
36834d8a380SJack Steiner unsigned int tfm_done_bit_enable:1;
36934d8a380SJack Steiner unsigned int unused:3;
37034d8a380SJack Steiner
37134d8a380SJack Steiner unsigned int dsr_allocation_map;
37234d8a380SJack Steiner
37334d8a380SJack Steiner unsigned long cbr_allocation_map; /* DW1 */
37434d8a380SJack Steiner
37534d8a380SJack Steiner unsigned int asid[8]; /* DW 2 - 5 */
37634d8a380SJack Steiner unsigned short sizeavail[8]; /* DW 6 - 7 */
37734d8a380SJack Steiner } __attribute__ ((packed));
37834d8a380SJack Steiner
37934d8a380SJack Steiner enum gru_cch_opc {
38034d8a380SJack Steiner CCHOP_START = 1,
38134d8a380SJack Steiner CCHOP_ALLOCATE,
38234d8a380SJack Steiner CCHOP_INTERRUPT,
38334d8a380SJack Steiner CCHOP_DEALLOCATE,
38434d8a380SJack Steiner CCHOP_INTERRUPT_SYNC,
38534d8a380SJack Steiner };
38634d8a380SJack Steiner
38734d8a380SJack Steiner enum gru_cch_status {
38834d8a380SJack Steiner CCHSTATUS_IDLE,
38934d8a380SJack Steiner CCHSTATUS_EXCEPTION,
39034d8a380SJack Steiner CCHSTATUS_ACTIVE,
39134d8a380SJack Steiner };
39234d8a380SJack Steiner
39334d8a380SJack Steiner enum gru_cch_state {
39434d8a380SJack Steiner CCHSTATE_INACTIVE,
39534d8a380SJack Steiner CCHSTATE_MAPPED,
39634d8a380SJack Steiner CCHSTATE_ACTIVE,
39734d8a380SJack Steiner CCHSTATE_INTERRUPTED,
39834d8a380SJack Steiner };
39934d8a380SJack Steiner
40034d8a380SJack Steiner /* CCH Exception cause */
40134d8a380SJack Steiner enum gru_cch_cause {
40234d8a380SJack Steiner CCHCAUSE_REGION_REGISTER_WRITE_ERROR = 1,
40334d8a380SJack Steiner CCHCAUSE_ILLEGAL_OPCODE = 2,
40434d8a380SJack Steiner CCHCAUSE_INVALID_START_REQUEST = 3,
40534d8a380SJack Steiner CCHCAUSE_INVALID_ALLOCATION_REQUEST = 4,
40634d8a380SJack Steiner CCHCAUSE_INVALID_DEALLOCATION_REQUEST = 5,
40734d8a380SJack Steiner CCHCAUSE_INVALID_INTERRUPT_REQUEST = 6,
40834d8a380SJack Steiner CCHCAUSE_CCH_BUSY = 7,
40934d8a380SJack Steiner CCHCAUSE_NO_CBRS_TO_ALLOCATE = 8,
41034d8a380SJack Steiner CCHCAUSE_BAD_TFM_CONFIG = 9,
41134d8a380SJack Steiner CCHCAUSE_CBR_RESOURCES_OVERSUBSCRIPED = 10,
41234d8a380SJack Steiner CCHCAUSE_DSR_RESOURCES_OVERSUBSCRIPED = 11,
41334d8a380SJack Steiner CCHCAUSE_CBR_DEALLOCATION_ERROR = 12,
41434d8a380SJack Steiner };
41534d8a380SJack Steiner /*
41634d8a380SJack Steiner * CBE - Control Block Extended
41734d8a380SJack Steiner * Maintains internal GRU state for active CBs.
41834d8a380SJack Steiner *
41934d8a380SJack Steiner */
42034d8a380SJack Steiner struct gru_control_block_extended {
42134d8a380SJack Steiner unsigned int reserved0:1; /* DW 0 - low */
42234d8a380SJack Steiner unsigned int imacpy:3;
42334d8a380SJack Steiner unsigned int reserved1:4;
42434d8a380SJack Steiner unsigned int xtypecpy:3;
42534d8a380SJack Steiner unsigned int iaa0cpy:2;
42634d8a380SJack Steiner unsigned int iaa1cpy:2;
42734d8a380SJack Steiner unsigned int reserved2:1;
42834d8a380SJack Steiner unsigned int opccpy:8;
42934d8a380SJack Steiner unsigned int exopccpy:8;
43034d8a380SJack Steiner
43134d8a380SJack Steiner unsigned int idef2cpy:22; /* DW 0 - high */
43234d8a380SJack Steiner unsigned int reserved3:10;
43334d8a380SJack Steiner
43434d8a380SJack Steiner unsigned int idef4cpy:22; /* DW 1 */
43534d8a380SJack Steiner unsigned int reserved4:10;
43634d8a380SJack Steiner unsigned int idef4upd:22;
43734d8a380SJack Steiner unsigned int reserved5:10;
43834d8a380SJack Steiner
43934d8a380SJack Steiner unsigned long idef1upd:64; /* DW 2 */
44034d8a380SJack Steiner
44134d8a380SJack Steiner unsigned long idef5cpy:64; /* DW 3 */
44234d8a380SJack Steiner
44334d8a380SJack Steiner unsigned long idef6cpy:64; /* DW 4 */
44434d8a380SJack Steiner
44534d8a380SJack Steiner unsigned long idef3upd:64; /* DW 5 */
44634d8a380SJack Steiner
44734d8a380SJack Steiner unsigned long idef5upd:64; /* DW 6 */
44834d8a380SJack Steiner
44934d8a380SJack Steiner unsigned int idef2upd:22; /* DW 7 */
45034d8a380SJack Steiner unsigned int reserved6:10;
45134d8a380SJack Steiner
45234d8a380SJack Steiner unsigned int ecause:20;
45334d8a380SJack Steiner unsigned int cbrstate:4;
45434d8a380SJack Steiner unsigned int cbrexecstatus:8;
45534d8a380SJack Steiner };
45634d8a380SJack Steiner
457c550222fSJack Steiner /* CBE fields for active BCOPY instructions */
458c550222fSJack Steiner #define cbe_baddr0 idef1upd
459c550222fSJack Steiner #define cbe_baddr1 idef3upd
460c550222fSJack Steiner #define cbe_src_cl idef6cpy
461c550222fSJack Steiner #define cbe_nelemcur idef5upd
462c550222fSJack Steiner
46334d8a380SJack Steiner enum gru_cbr_state {
46434d8a380SJack Steiner CBRSTATE_INACTIVE,
46534d8a380SJack Steiner CBRSTATE_IDLE,
46634d8a380SJack Steiner CBRSTATE_PE_CHECK,
46734d8a380SJack Steiner CBRSTATE_QUEUED,
46834d8a380SJack Steiner CBRSTATE_WAIT_RESPONSE,
46934d8a380SJack Steiner CBRSTATE_INTERRUPTED,
47034d8a380SJack Steiner CBRSTATE_INTERRUPTED_MISS_FMM,
47134d8a380SJack Steiner CBRSTATE_BUSY_INTERRUPT_MISS_FMM,
47234d8a380SJack Steiner CBRSTATE_INTERRUPTED_MISS_UPM,
47334d8a380SJack Steiner CBRSTATE_BUSY_INTERRUPTED_MISS_UPM,
47434d8a380SJack Steiner CBRSTATE_REQUEST_ISSUE,
47534d8a380SJack Steiner CBRSTATE_BUSY_INTERRUPT,
47634d8a380SJack Steiner };
47734d8a380SJack Steiner
478cd1334f0SJack Steiner /* CBE cbrexecstatus bits - defined in gru_instructions.h*/
47934d8a380SJack Steiner /* CBE ecause bits - defined in gru_instructions.h */
48034d8a380SJack Steiner
48134d8a380SJack Steiner /*
48234d8a380SJack Steiner * Convert a processor pagesize into the strange encoded pagesize used by the
48334d8a380SJack Steiner * GRU. Processor pagesize is encoded as log of bytes per page. (or PAGE_SHIFT)
48434d8a380SJack Steiner * pagesize log pagesize grupagesize
48534d8a380SJack Steiner * 4k 12 0
48634d8a380SJack Steiner * 16k 14 1
48734d8a380SJack Steiner * 64k 16 2
48834d8a380SJack Steiner * 256k 18 3
48934d8a380SJack Steiner * 1m 20 4
49034d8a380SJack Steiner * 2m 21 5
49134d8a380SJack Steiner * 4m 22 6
49234d8a380SJack Steiner * 16m 24 7
49334d8a380SJack Steiner * 64m 26 8
49434d8a380SJack Steiner * ...
49534d8a380SJack Steiner */
49634d8a380SJack Steiner #define GRU_PAGESIZE(sh) ((((sh) > 20 ? (sh) + 2 : (sh)) >> 1) - 6)
49734d8a380SJack Steiner #define GRU_SIZEAVAIL(sh) (1UL << GRU_PAGESIZE(sh))
49834d8a380SJack Steiner
49934d8a380SJack Steiner /* minimum TLB purge count to ensure a full purge */
50034d8a380SJack Steiner #define GRUMAXINVAL 1024UL
50134d8a380SJack Steiner
5026e910074SJack Steiner int cch_allocate(struct gru_context_configuration_handle *cch);
503a24e5e1cSJack Steiner int cch_start(struct gru_context_configuration_handle *cch);
504a24e5e1cSJack Steiner int cch_interrupt(struct gru_context_configuration_handle *cch);
505a24e5e1cSJack Steiner int cch_deallocate(struct gru_context_configuration_handle *cch);
506a24e5e1cSJack Steiner int cch_interrupt_sync(struct gru_context_configuration_handle *cch);
507a24e5e1cSJack Steiner int tgh_invalidate(struct gru_tlb_global_handle *tgh, unsigned long vaddr,
508a24e5e1cSJack Steiner unsigned long vaddrmask, int asid, int pagesize, int global, int n,
509a24e5e1cSJack Steiner unsigned short ctxbitmap);
510c550222fSJack Steiner int tfh_write_only(struct gru_tlb_fault_handle *tfh, unsigned long paddr,
511c550222fSJack Steiner int gaa, unsigned long vaddr, int asid, int dirty, int pagesize);
512a24e5e1cSJack Steiner void tfh_write_restart(struct gru_tlb_fault_handle *tfh, unsigned long paddr,
513a24e5e1cSJack Steiner int gaa, unsigned long vaddr, int asid, int dirty, int pagesize);
514a24e5e1cSJack Steiner void tfh_user_polling_mode(struct gru_tlb_fault_handle *tfh);
515a24e5e1cSJack Steiner void tfh_exception(struct gru_tlb_fault_handle *tfh);
51634d8a380SJack Steiner
51734d8a380SJack Steiner #endif /* __GRUHANDLES_H__ */
518