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