134d8a380SJack Steiner /*
234d8a380SJack Steiner  * SN Platform GRU Driver
334d8a380SJack Steiner  *
434d8a380SJack Steiner  *              GRU HANDLE DEFINITION
534d8a380SJack Steiner  *
634d8a380SJack Steiner  *  Copyright (c) 2008 Silicon Graphics, Inc.  All Rights Reserved.
734d8a380SJack Steiner  *
834d8a380SJack Steiner  *  This program is free software; you can redistribute it and/or modify
934d8a380SJack Steiner  *  it under the terms of the GNU General Public License as published by
1034d8a380SJack Steiner  *  the Free Software Foundation; either version 2 of the License, or
1134d8a380SJack Steiner  *  (at your option) any later version.
1234d8a380SJack Steiner  *
1334d8a380SJack Steiner  *  This program is distributed in the hope that it will be useful,
1434d8a380SJack Steiner  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
1534d8a380SJack Steiner  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1634d8a380SJack Steiner  *  GNU General Public License for more details.
1734d8a380SJack Steiner  *
1834d8a380SJack Steiner  *  You should have received a copy of the GNU General Public License
1934d8a380SJack Steiner  *  along with this program; if not, write to the Free Software
2034d8a380SJack Steiner  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
2134d8a380SJack Steiner  */
2234d8a380SJack Steiner 
2334d8a380SJack Steiner #ifndef __GRUHANDLES_H__
2434d8a380SJack Steiner #define __GRUHANDLES_H__
2534d8a380SJack Steiner #include "gru_instructions.h"
2634d8a380SJack Steiner 
2734d8a380SJack Steiner /*
2834d8a380SJack Steiner  * Manifest constants for GRU Memory Map
2934d8a380SJack Steiner  */
3034d8a380SJack Steiner #define GRU_GSEG0_BASE		0
3134d8a380SJack Steiner #define GRU_MCS_BASE		(64 * 1024 * 1024)
3234d8a380SJack Steiner #define GRU_SIZE		(128UL * 1024 * 1024)
3334d8a380SJack Steiner 
3434d8a380SJack Steiner /* Handle & resource counts */
3534d8a380SJack Steiner #define GRU_NUM_CB		128
3634d8a380SJack Steiner #define GRU_NUM_DSR_BYTES	(32 * 1024)
3734d8a380SJack Steiner #define GRU_NUM_TFM		16
3834d8a380SJack Steiner #define GRU_NUM_TGH		24
3934d8a380SJack Steiner #define GRU_NUM_CBE		128
4034d8a380SJack Steiner #define GRU_NUM_TFH		128
4134d8a380SJack Steiner #define GRU_NUM_CCH		16
4234d8a380SJack Steiner 
4334d8a380SJack Steiner /* Maximum resource counts that can be reserved by user programs */
4434d8a380SJack Steiner #define GRU_NUM_USER_CBR	GRU_NUM_CBE
4534d8a380SJack Steiner #define GRU_NUM_USER_DSR_BYTES	GRU_NUM_DSR_BYTES
4634d8a380SJack Steiner 
4734d8a380SJack Steiner /* Bytes per handle & handle stride. Code assumes all cb, tfh, cbe handles
4834d8a380SJack Steiner  * are the same */
4934d8a380SJack Steiner #define GRU_HANDLE_BYTES	64
5034d8a380SJack Steiner #define GRU_HANDLE_STRIDE	256
5134d8a380SJack Steiner 
5234d8a380SJack Steiner /* Base addresses of handles */
5334d8a380SJack Steiner #define GRU_TFM_BASE		(GRU_MCS_BASE + 0x00000)
5434d8a380SJack Steiner #define GRU_TGH_BASE		(GRU_MCS_BASE + 0x08000)
5534d8a380SJack Steiner #define GRU_CBE_BASE		(GRU_MCS_BASE + 0x10000)
5634d8a380SJack Steiner #define GRU_TFH_BASE		(GRU_MCS_BASE + 0x18000)
5734d8a380SJack Steiner #define GRU_CCH_BASE		(GRU_MCS_BASE + 0x20000)
5834d8a380SJack Steiner 
5934d8a380SJack Steiner /* User gseg constants */
6034d8a380SJack Steiner #define GRU_GSEG_STRIDE		(4 * 1024 * 1024)
6134d8a380SJack Steiner #define GSEG_BASE(a)		((a) & ~(GRU_GSEG_PAGESIZE - 1))
6234d8a380SJack Steiner 
6334d8a380SJack Steiner /* Data segment constants */
6434d8a380SJack Steiner #define GRU_DSR_AU_BYTES	1024
6534d8a380SJack Steiner #define GRU_DSR_CL		(GRU_NUM_DSR_BYTES / GRU_CACHE_LINE_BYTES)
6634d8a380SJack Steiner #define GRU_DSR_AU_CL		(GRU_DSR_AU_BYTES / GRU_CACHE_LINE_BYTES)
6734d8a380SJack Steiner #define GRU_DSR_AU		(GRU_NUM_DSR_BYTES / GRU_DSR_AU_BYTES)
6834d8a380SJack Steiner 
6934d8a380SJack Steiner /* Control block constants */
7034d8a380SJack Steiner #define GRU_CBR_AU_SIZE		2
7134d8a380SJack Steiner #define GRU_CBR_AU		(GRU_NUM_CBE / GRU_CBR_AU_SIZE)
7234d8a380SJack Steiner 
7334d8a380SJack Steiner /* Convert resource counts to the number of AU */
7434d8a380SJack Steiner #define GRU_DS_BYTES_TO_AU(n)	DIV_ROUND_UP(n, GRU_DSR_AU_BYTES)
7534d8a380SJack Steiner #define GRU_CB_COUNT_TO_AU(n)	DIV_ROUND_UP(n, GRU_CBR_AU_SIZE)
7634d8a380SJack Steiner 
7734d8a380SJack Steiner /* UV limits */
7834d8a380SJack Steiner #define GRU_CHIPLETS_PER_HUB	2
7934d8a380SJack Steiner #define GRU_HUBS_PER_BLADE	1
8034d8a380SJack Steiner #define GRU_CHIPLETS_PER_BLADE	(GRU_HUBS_PER_BLADE * GRU_CHIPLETS_PER_HUB)
8134d8a380SJack Steiner 
8234d8a380SJack Steiner /* User GRU Gseg offsets */
8334d8a380SJack Steiner #define GRU_CB_BASE		0
8434d8a380SJack Steiner #define GRU_CB_LIMIT		(GRU_CB_BASE + GRU_HANDLE_STRIDE * GRU_NUM_CBE)
8534d8a380SJack Steiner #define GRU_DS_BASE		0x20000
8634d8a380SJack Steiner #define GRU_DS_LIMIT		(GRU_DS_BASE + GRU_NUM_DSR_BYTES)
8734d8a380SJack Steiner 
8834d8a380SJack Steiner /* Convert a GRU physical address to the chiplet offset */
8934d8a380SJack Steiner #define GSEGPOFF(h) 		((h) & (GRU_SIZE - 1))
9034d8a380SJack Steiner 
9134d8a380SJack Steiner /* Convert an arbitrary handle address to the beginning of the GRU segment */
9234d8a380SJack Steiner #define GRUBASE(h)		((void *)((unsigned long)(h) & ~(GRU_SIZE - 1)))
9334d8a380SJack Steiner 
94648eb8e5SJack Steiner /* Test a valid handle address to determine the type */
95648eb8e5SJack Steiner #define TYPE_IS(hn, h)		((h) >= GRU_##hn##_BASE && (h) <	\
96648eb8e5SJack Steiner 		GRU_##hn##_BASE + GRU_NUM_##hn * GRU_HANDLE_STRIDE &&   \
97648eb8e5SJack Steiner 		(((h) & (GRU_HANDLE_STRIDE - 1)) == 0))
98648eb8e5SJack Steiner 
99648eb8e5SJack Steiner 
10034d8a380SJack Steiner /* General addressing macros. */
10134d8a380SJack Steiner static inline void *get_gseg_base_address(void *base, int ctxnum)
10234d8a380SJack Steiner {
10334d8a380SJack Steiner 	return (void *)(base + GRU_GSEG0_BASE + GRU_GSEG_STRIDE * ctxnum);
10434d8a380SJack Steiner }
10534d8a380SJack Steiner 
10634d8a380SJack Steiner static inline void *get_gseg_base_address_cb(void *base, int ctxnum, int line)
10734d8a380SJack Steiner {
10834d8a380SJack Steiner 	return (void *)(get_gseg_base_address(base, ctxnum) +
10934d8a380SJack Steiner 			GRU_CB_BASE + GRU_HANDLE_STRIDE * line);
11034d8a380SJack Steiner }
11134d8a380SJack Steiner 
11234d8a380SJack Steiner static inline void *get_gseg_base_address_ds(void *base, int ctxnum, int line)
11334d8a380SJack Steiner {
11434d8a380SJack Steiner 	return (void *)(get_gseg_base_address(base, ctxnum) + GRU_DS_BASE +
11534d8a380SJack Steiner 			GRU_CACHE_LINE_BYTES * line);
11634d8a380SJack Steiner }
11734d8a380SJack Steiner 
11834d8a380SJack Steiner static inline struct gru_tlb_fault_map *get_tfm(void *base, int ctxnum)
11934d8a380SJack Steiner {
12034d8a380SJack Steiner 	return (struct gru_tlb_fault_map *)(base + GRU_TFM_BASE +
12134d8a380SJack Steiner 					ctxnum * GRU_HANDLE_STRIDE);
12234d8a380SJack Steiner }
12334d8a380SJack Steiner 
12434d8a380SJack Steiner static inline struct gru_tlb_global_handle *get_tgh(void *base, int ctxnum)
12534d8a380SJack Steiner {
12634d8a380SJack Steiner 	return (struct gru_tlb_global_handle *)(base + GRU_TGH_BASE +
12734d8a380SJack Steiner 					ctxnum * GRU_HANDLE_STRIDE);
12834d8a380SJack Steiner }
12934d8a380SJack Steiner 
13034d8a380SJack Steiner static inline struct gru_control_block_extended *get_cbe(void *base, int ctxnum)
13134d8a380SJack Steiner {
13234d8a380SJack Steiner 	return (struct gru_control_block_extended *)(base + GRU_CBE_BASE +
13334d8a380SJack Steiner 					ctxnum * GRU_HANDLE_STRIDE);
13434d8a380SJack Steiner }
13534d8a380SJack Steiner 
13634d8a380SJack Steiner static inline struct gru_tlb_fault_handle *get_tfh(void *base, int ctxnum)
13734d8a380SJack Steiner {
13834d8a380SJack Steiner 	return (struct gru_tlb_fault_handle *)(base + GRU_TFH_BASE +
13934d8a380SJack Steiner 					ctxnum * GRU_HANDLE_STRIDE);
14034d8a380SJack Steiner }
14134d8a380SJack Steiner 
14234d8a380SJack Steiner static inline struct gru_context_configuration_handle *get_cch(void *base,
14334d8a380SJack Steiner 					int ctxnum)
14434d8a380SJack Steiner {
14534d8a380SJack Steiner 	return (struct gru_context_configuration_handle *)(base +
14634d8a380SJack Steiner 				GRU_CCH_BASE + ctxnum * GRU_HANDLE_STRIDE);
14734d8a380SJack Steiner }
14834d8a380SJack Steiner 
14934d8a380SJack Steiner static inline unsigned long get_cb_number(void *cb)
15034d8a380SJack Steiner {
15134d8a380SJack Steiner 	return (((unsigned long)cb - GRU_CB_BASE) % GRU_GSEG_PAGESIZE) /
15234d8a380SJack Steiner 					GRU_HANDLE_STRIDE;
15334d8a380SJack Steiner }
15434d8a380SJack Steiner 
15534d8a380SJack Steiner /* byte offset to a specific GRU chiplet. (p=pnode, c=chiplet (0 or 1)*/
15634d8a380SJack Steiner static inline unsigned long gru_chiplet_paddr(unsigned long paddr, int pnode,
15734d8a380SJack Steiner 							int chiplet)
15834d8a380SJack Steiner {
15934d8a380SJack Steiner 	return paddr + GRU_SIZE * (2 * pnode  + chiplet);
16034d8a380SJack Steiner }
16134d8a380SJack Steiner 
16234d8a380SJack Steiner static inline void *gru_chiplet_vaddr(void *vaddr, int pnode, int chiplet)
16334d8a380SJack Steiner {
16434d8a380SJack Steiner 	return vaddr + GRU_SIZE * (2 * pnode  + chiplet);
16534d8a380SJack Steiner }
16634d8a380SJack Steiner 
167c550222fSJack Steiner static inline struct gru_control_block_extended *gru_tfh_to_cbe(
168c550222fSJack Steiner 					struct gru_tlb_fault_handle *tfh)
169c550222fSJack Steiner {
170c550222fSJack Steiner 	unsigned long cbe;
171c550222fSJack Steiner 
172c550222fSJack Steiner 	cbe = (unsigned long)tfh - GRU_TFH_BASE + GRU_CBE_BASE;
173c550222fSJack Steiner 	return (struct gru_control_block_extended*)cbe;
174c550222fSJack Steiner }
175c550222fSJack Steiner 
176c550222fSJack Steiner 
17734d8a380SJack Steiner 
17834d8a380SJack Steiner 
17934d8a380SJack Steiner /*
18034d8a380SJack Steiner  * Global TLB Fault Map
18134d8a380SJack Steiner  * 	Bitmap of outstanding TLB misses needing interrupt/polling service.
18234d8a380SJack Steiner  *
18334d8a380SJack Steiner  */
18434d8a380SJack Steiner struct gru_tlb_fault_map {
18534d8a380SJack Steiner 	unsigned long fault_bits[BITS_TO_LONGS(GRU_NUM_CBE)];
18634d8a380SJack Steiner 	unsigned long fill0[2];
18734d8a380SJack Steiner 	unsigned long done_bits[BITS_TO_LONGS(GRU_NUM_CBE)];
18834d8a380SJack Steiner 	unsigned long fill1[2];
18934d8a380SJack Steiner };
19034d8a380SJack Steiner 
19134d8a380SJack Steiner /*
19234d8a380SJack Steiner  * TGH - TLB Global Handle
19334d8a380SJack Steiner  * 	Used for TLB flushing.
19434d8a380SJack Steiner  *
19534d8a380SJack Steiner  */
19634d8a380SJack Steiner struct gru_tlb_global_handle {
19734d8a380SJack Steiner 	unsigned int cmd:1;		/* DW 0 */
19834d8a380SJack Steiner 	unsigned int delresp:1;
19934d8a380SJack Steiner 	unsigned int opc:1;
20034d8a380SJack Steiner 	unsigned int fill1:5;
20134d8a380SJack Steiner 
20234d8a380SJack Steiner 	unsigned int fill2:8;
20334d8a380SJack Steiner 
20434d8a380SJack Steiner 	unsigned int status:2;
20534d8a380SJack Steiner 	unsigned long fill3:2;
20634d8a380SJack Steiner 	unsigned int state:3;
20734d8a380SJack Steiner 	unsigned long fill4:1;
20834d8a380SJack Steiner 
20934d8a380SJack Steiner 	unsigned int cause:3;
21034d8a380SJack Steiner 	unsigned long fill5:37;
21134d8a380SJack Steiner 
21234d8a380SJack Steiner 	unsigned long vaddr:64;		/* DW 1 */
21334d8a380SJack Steiner 
21434d8a380SJack Steiner 	unsigned int asid:24;		/* DW 2 */
21534d8a380SJack Steiner 	unsigned int fill6:8;
21634d8a380SJack Steiner 
21734d8a380SJack Steiner 	unsigned int pagesize:5;
21834d8a380SJack Steiner 	unsigned int fill7:11;
21934d8a380SJack Steiner 
22034d8a380SJack Steiner 	unsigned int global:1;
22134d8a380SJack Steiner 	unsigned int fill8:15;
22234d8a380SJack Steiner 
22334d8a380SJack Steiner 	unsigned long vaddrmask:39;	/* DW 3 */
22434d8a380SJack Steiner 	unsigned int fill9:9;
22534d8a380SJack Steiner 	unsigned int n:10;
22634d8a380SJack Steiner 	unsigned int fill10:6;
22734d8a380SJack Steiner 
22834d8a380SJack Steiner 	unsigned int ctxbitmap:16;	/* DW4 */
22934d8a380SJack Steiner 	unsigned long fill11[3];
23034d8a380SJack Steiner };
23134d8a380SJack Steiner 
23234d8a380SJack Steiner enum gru_tgh_cmd {
23334d8a380SJack Steiner 	TGHCMD_START
23434d8a380SJack Steiner };
23534d8a380SJack Steiner 
23634d8a380SJack Steiner enum gru_tgh_opc {
23734d8a380SJack Steiner 	TGHOP_TLBNOP,
23834d8a380SJack Steiner 	TGHOP_TLBINV
23934d8a380SJack Steiner };
24034d8a380SJack Steiner 
24134d8a380SJack Steiner enum gru_tgh_status {
24234d8a380SJack Steiner 	TGHSTATUS_IDLE,
24334d8a380SJack Steiner 	TGHSTATUS_EXCEPTION,
24434d8a380SJack Steiner 	TGHSTATUS_ACTIVE
24534d8a380SJack Steiner };
24634d8a380SJack Steiner 
24734d8a380SJack Steiner enum gru_tgh_state {
24834d8a380SJack Steiner 	TGHSTATE_IDLE,
24934d8a380SJack Steiner 	TGHSTATE_PE_INVAL,
25034d8a380SJack Steiner 	TGHSTATE_INTERRUPT_INVAL,
25134d8a380SJack Steiner 	TGHSTATE_WAITDONE,
25234d8a380SJack Steiner 	TGHSTATE_RESTART_CTX,
25334d8a380SJack Steiner };
25434d8a380SJack Steiner 
2555658366aSJack Steiner enum gru_tgh_cause {
2565658366aSJack Steiner 	TGHCAUSE_RR_ECC,
2575658366aSJack Steiner 	TGHCAUSE_TLB_ECC,
2585658366aSJack Steiner 	TGHCAUSE_LRU_ECC,
2595658366aSJack Steiner 	TGHCAUSE_PS_ECC,
2605658366aSJack Steiner 	TGHCAUSE_MUL_ERR,
2615658366aSJack Steiner 	TGHCAUSE_DATA_ERR,
2625658366aSJack Steiner 	TGHCAUSE_SW_FORCE
2635658366aSJack Steiner };
2645658366aSJack Steiner 
2655658366aSJack Steiner 
26634d8a380SJack Steiner /*
26734d8a380SJack Steiner  * TFH - TLB Global Handle
26834d8a380SJack Steiner  * 	Used for TLB dropins into the GRU TLB.
26934d8a380SJack Steiner  *
27034d8a380SJack Steiner  */
27134d8a380SJack Steiner struct gru_tlb_fault_handle {
27234d8a380SJack Steiner 	unsigned int cmd:1;		/* DW 0 - low 32*/
27334d8a380SJack Steiner 	unsigned int delresp:1;
27434d8a380SJack Steiner 	unsigned int fill0:2;
27534d8a380SJack Steiner 	unsigned int opc:3;
27634d8a380SJack Steiner 	unsigned int fill1:9;
27734d8a380SJack Steiner 
27834d8a380SJack Steiner 	unsigned int status:2;
279cd1334f0SJack Steiner 	unsigned int fill2:2;
28034d8a380SJack Steiner 	unsigned int state:3;
28134d8a380SJack Steiner 	unsigned int fill3:1;
28234d8a380SJack Steiner 
283270952a9SJack Steiner 	unsigned int cause:6;
284270952a9SJack Steiner 	unsigned int cb_int:1;
28534d8a380SJack Steiner 	unsigned int fill4:1;
28634d8a380SJack Steiner 
287cd1334f0SJack Steiner 	unsigned int indexway:12;	/* DW 0 - high 32 */
28834d8a380SJack Steiner 	unsigned int fill5:4;
28934d8a380SJack Steiner 
29034d8a380SJack Steiner 	unsigned int ctxnum:4;
29134d8a380SJack Steiner 	unsigned int fill6:12;
29234d8a380SJack Steiner 
29334d8a380SJack Steiner 	unsigned long missvaddr:64;	/* DW 1 */
29434d8a380SJack Steiner 
29534d8a380SJack Steiner 	unsigned int missasid:24;	/* DW 2 */
29634d8a380SJack Steiner 	unsigned int fill7:8;
29734d8a380SJack Steiner 	unsigned int fillasid:24;
29834d8a380SJack Steiner 	unsigned int dirty:1;
29934d8a380SJack Steiner 	unsigned int gaa:2;
30034d8a380SJack Steiner 	unsigned long fill8:5;
30134d8a380SJack Steiner 
30234d8a380SJack Steiner 	unsigned long pfn:41;		/* DW 3 */
30334d8a380SJack Steiner 	unsigned int fill9:7;
30434d8a380SJack Steiner 	unsigned int pagesize:5;
30534d8a380SJack Steiner 	unsigned int fill10:11;
30634d8a380SJack Steiner 
30734d8a380SJack Steiner 	unsigned long fillvaddr:64;	/* DW 4 */
30834d8a380SJack Steiner 
30934d8a380SJack Steiner 	unsigned long fill11[3];
31034d8a380SJack Steiner };
31134d8a380SJack Steiner 
31234d8a380SJack Steiner enum gru_tfh_opc {
31334d8a380SJack Steiner 	TFHOP_NOOP,
31434d8a380SJack Steiner 	TFHOP_RESTART,
31534d8a380SJack Steiner 	TFHOP_WRITE_ONLY,
31634d8a380SJack Steiner 	TFHOP_WRITE_RESTART,
31734d8a380SJack Steiner 	TFHOP_EXCEPTION,
31834d8a380SJack Steiner 	TFHOP_USER_POLLING_MODE = 7,
31934d8a380SJack Steiner };
32034d8a380SJack Steiner 
32134d8a380SJack Steiner enum tfh_status {
32234d8a380SJack Steiner 	TFHSTATUS_IDLE,
32334d8a380SJack Steiner 	TFHSTATUS_EXCEPTION,
32434d8a380SJack Steiner 	TFHSTATUS_ACTIVE,
32534d8a380SJack Steiner };
32634d8a380SJack Steiner 
32734d8a380SJack Steiner enum tfh_state {
32834d8a380SJack Steiner 	TFHSTATE_INACTIVE,
32934d8a380SJack Steiner 	TFHSTATE_IDLE,
33034d8a380SJack Steiner 	TFHSTATE_MISS_UPM,
33134d8a380SJack Steiner 	TFHSTATE_MISS_FMM,
33234d8a380SJack Steiner 	TFHSTATE_HW_ERR,
33334d8a380SJack Steiner 	TFHSTATE_WRITE_TLB,
33434d8a380SJack Steiner 	TFHSTATE_RESTART_CBR,
33534d8a380SJack Steiner };
33634d8a380SJack Steiner 
33734d8a380SJack Steiner /* TFH cause bits */
33834d8a380SJack Steiner enum tfh_cause {
33934d8a380SJack Steiner 	TFHCAUSE_NONE,
34034d8a380SJack Steiner 	TFHCAUSE_TLB_MISS,
34134d8a380SJack Steiner 	TFHCAUSE_TLB_MOD,
34234d8a380SJack Steiner 	TFHCAUSE_HW_ERROR_RR,
34334d8a380SJack Steiner 	TFHCAUSE_HW_ERROR_MAIN_ARRAY,
34434d8a380SJack Steiner 	TFHCAUSE_HW_ERROR_VALID,
34534d8a380SJack Steiner 	TFHCAUSE_HW_ERROR_PAGESIZE,
34634d8a380SJack Steiner 	TFHCAUSE_INSTRUCTION_EXCEPTION,
34734d8a380SJack Steiner 	TFHCAUSE_UNCORRECTIBLE_ERROR,
34834d8a380SJack Steiner };
34934d8a380SJack Steiner 
35034d8a380SJack Steiner /* GAA values */
35134d8a380SJack Steiner #define GAA_RAM				0x0
35234d8a380SJack Steiner #define GAA_NCRAM			0x2
35334d8a380SJack Steiner #define GAA_MMIO			0x1
35434d8a380SJack Steiner #define GAA_REGISTER			0x3
35534d8a380SJack Steiner 
35634d8a380SJack Steiner /* GRU paddr shift for pfn. (NOTE: shift is NOT by actual pagesize) */
35734d8a380SJack Steiner #define GRU_PADDR_SHIFT			12
35834d8a380SJack Steiner 
35934d8a380SJack Steiner /*
36034d8a380SJack Steiner  * Context Configuration handle
36134d8a380SJack Steiner  * 	Used to allocate resources to a GSEG context.
36234d8a380SJack Steiner  *
36334d8a380SJack Steiner  */
36434d8a380SJack Steiner struct gru_context_configuration_handle {
36534d8a380SJack Steiner 	unsigned int cmd:1;			/* DW0 */
36634d8a380SJack Steiner 	unsigned int delresp:1;
36734d8a380SJack Steiner 	unsigned int opc:3;
36834d8a380SJack Steiner 	unsigned int unmap_enable:1;
36934d8a380SJack Steiner 	unsigned int req_slice_set_enable:1;
37034d8a380SJack Steiner 	unsigned int req_slice:2;
37134d8a380SJack Steiner 	unsigned int cb_int_enable:1;
37234d8a380SJack Steiner 	unsigned int tlb_int_enable:1;
37334d8a380SJack Steiner 	unsigned int tfm_fault_bit_enable:1;
37434d8a380SJack Steiner 	unsigned int tlb_int_select:4;
37534d8a380SJack Steiner 
37634d8a380SJack Steiner 	unsigned int status:2;
37734d8a380SJack Steiner 	unsigned int state:2;
37834d8a380SJack Steiner 	unsigned int reserved2:4;
37934d8a380SJack Steiner 
38034d8a380SJack Steiner 	unsigned int cause:4;
38134d8a380SJack Steiner 	unsigned int tfm_done_bit_enable:1;
38234d8a380SJack Steiner 	unsigned int unused:3;
38334d8a380SJack Steiner 
38434d8a380SJack Steiner 	unsigned int dsr_allocation_map;
38534d8a380SJack Steiner 
38634d8a380SJack Steiner 	unsigned long cbr_allocation_map;	/* DW1 */
38734d8a380SJack Steiner 
38834d8a380SJack Steiner 	unsigned int asid[8];			/* DW 2 - 5 */
38934d8a380SJack Steiner 	unsigned short sizeavail[8];		/* DW 6 - 7 */
39034d8a380SJack Steiner } __attribute__ ((packed));
39134d8a380SJack Steiner 
39234d8a380SJack Steiner enum gru_cch_opc {
39334d8a380SJack Steiner 	CCHOP_START = 1,
39434d8a380SJack Steiner 	CCHOP_ALLOCATE,
39534d8a380SJack Steiner 	CCHOP_INTERRUPT,
39634d8a380SJack Steiner 	CCHOP_DEALLOCATE,
39734d8a380SJack Steiner 	CCHOP_INTERRUPT_SYNC,
39834d8a380SJack Steiner };
39934d8a380SJack Steiner 
40034d8a380SJack Steiner enum gru_cch_status {
40134d8a380SJack Steiner 	CCHSTATUS_IDLE,
40234d8a380SJack Steiner 	CCHSTATUS_EXCEPTION,
40334d8a380SJack Steiner 	CCHSTATUS_ACTIVE,
40434d8a380SJack Steiner };
40534d8a380SJack Steiner 
40634d8a380SJack Steiner enum gru_cch_state {
40734d8a380SJack Steiner 	CCHSTATE_INACTIVE,
40834d8a380SJack Steiner 	CCHSTATE_MAPPED,
40934d8a380SJack Steiner 	CCHSTATE_ACTIVE,
41034d8a380SJack Steiner 	CCHSTATE_INTERRUPTED,
41134d8a380SJack Steiner };
41234d8a380SJack Steiner 
41334d8a380SJack Steiner /* CCH Exception cause */
41434d8a380SJack Steiner enum gru_cch_cause {
41534d8a380SJack Steiner 	CCHCAUSE_REGION_REGISTER_WRITE_ERROR = 1,
41634d8a380SJack Steiner 	CCHCAUSE_ILLEGAL_OPCODE = 2,
41734d8a380SJack Steiner 	CCHCAUSE_INVALID_START_REQUEST = 3,
41834d8a380SJack Steiner 	CCHCAUSE_INVALID_ALLOCATION_REQUEST = 4,
41934d8a380SJack Steiner 	CCHCAUSE_INVALID_DEALLOCATION_REQUEST = 5,
42034d8a380SJack Steiner 	CCHCAUSE_INVALID_INTERRUPT_REQUEST = 6,
42134d8a380SJack Steiner 	CCHCAUSE_CCH_BUSY = 7,
42234d8a380SJack Steiner 	CCHCAUSE_NO_CBRS_TO_ALLOCATE = 8,
42334d8a380SJack Steiner 	CCHCAUSE_BAD_TFM_CONFIG = 9,
42434d8a380SJack Steiner 	CCHCAUSE_CBR_RESOURCES_OVERSUBSCRIPED = 10,
42534d8a380SJack Steiner 	CCHCAUSE_DSR_RESOURCES_OVERSUBSCRIPED = 11,
42634d8a380SJack Steiner 	CCHCAUSE_CBR_DEALLOCATION_ERROR = 12,
42734d8a380SJack Steiner };
42834d8a380SJack Steiner /*
42934d8a380SJack Steiner  * CBE - Control Block Extended
43034d8a380SJack Steiner  * 	Maintains internal GRU state for active CBs.
43134d8a380SJack Steiner  *
43234d8a380SJack Steiner  */
43334d8a380SJack Steiner struct gru_control_block_extended {
43434d8a380SJack Steiner 	unsigned int reserved0:1;	/* DW 0  - low */
43534d8a380SJack Steiner 	unsigned int imacpy:3;
43634d8a380SJack Steiner 	unsigned int reserved1:4;
43734d8a380SJack Steiner 	unsigned int xtypecpy:3;
43834d8a380SJack Steiner 	unsigned int iaa0cpy:2;
43934d8a380SJack Steiner 	unsigned int iaa1cpy:2;
44034d8a380SJack Steiner 	unsigned int reserved2:1;
44134d8a380SJack Steiner 	unsigned int opccpy:8;
44234d8a380SJack Steiner 	unsigned int exopccpy:8;
44334d8a380SJack Steiner 
44434d8a380SJack Steiner 	unsigned int idef2cpy:22;	/* DW 0  - high */
44534d8a380SJack Steiner 	unsigned int reserved3:10;
44634d8a380SJack Steiner 
44734d8a380SJack Steiner 	unsigned int idef4cpy:22;	/* DW 1 */
44834d8a380SJack Steiner 	unsigned int reserved4:10;
44934d8a380SJack Steiner 	unsigned int idef4upd:22;
45034d8a380SJack Steiner 	unsigned int reserved5:10;
45134d8a380SJack Steiner 
45234d8a380SJack Steiner 	unsigned long idef1upd:64;	/* DW 2 */
45334d8a380SJack Steiner 
45434d8a380SJack Steiner 	unsigned long idef5cpy:64;	/* DW 3 */
45534d8a380SJack Steiner 
45634d8a380SJack Steiner 	unsigned long idef6cpy:64;	/* DW 4 */
45734d8a380SJack Steiner 
45834d8a380SJack Steiner 	unsigned long idef3upd:64;	/* DW 5 */
45934d8a380SJack Steiner 
46034d8a380SJack Steiner 	unsigned long idef5upd:64;	/* DW 6 */
46134d8a380SJack Steiner 
46234d8a380SJack Steiner 	unsigned int idef2upd:22;	/* DW 7 */
46334d8a380SJack Steiner 	unsigned int reserved6:10;
46434d8a380SJack Steiner 
46534d8a380SJack Steiner 	unsigned int ecause:20;
46634d8a380SJack Steiner 	unsigned int cbrstate:4;
46734d8a380SJack Steiner 	unsigned int cbrexecstatus:8;
46834d8a380SJack Steiner };
46934d8a380SJack Steiner 
470c550222fSJack Steiner /* CBE fields for active BCOPY instructions */
471c550222fSJack Steiner #define cbe_baddr0	idef1upd
472c550222fSJack Steiner #define cbe_baddr1	idef3upd
473c550222fSJack Steiner #define cbe_src_cl	idef6cpy
474c550222fSJack Steiner #define cbe_nelemcur	idef5upd
475c550222fSJack Steiner 
47634d8a380SJack Steiner enum gru_cbr_state {
47734d8a380SJack Steiner 	CBRSTATE_INACTIVE,
47834d8a380SJack Steiner 	CBRSTATE_IDLE,
47934d8a380SJack Steiner 	CBRSTATE_PE_CHECK,
48034d8a380SJack Steiner 	CBRSTATE_QUEUED,
48134d8a380SJack Steiner 	CBRSTATE_WAIT_RESPONSE,
48234d8a380SJack Steiner 	CBRSTATE_INTERRUPTED,
48334d8a380SJack Steiner 	CBRSTATE_INTERRUPTED_MISS_FMM,
48434d8a380SJack Steiner 	CBRSTATE_BUSY_INTERRUPT_MISS_FMM,
48534d8a380SJack Steiner 	CBRSTATE_INTERRUPTED_MISS_UPM,
48634d8a380SJack Steiner 	CBRSTATE_BUSY_INTERRUPTED_MISS_UPM,
48734d8a380SJack Steiner 	CBRSTATE_REQUEST_ISSUE,
48834d8a380SJack Steiner 	CBRSTATE_BUSY_INTERRUPT,
48934d8a380SJack Steiner };
49034d8a380SJack Steiner 
491cd1334f0SJack Steiner /* CBE cbrexecstatus bits  - defined in gru_instructions.h*/
49234d8a380SJack Steiner /* CBE ecause bits  - defined in gru_instructions.h */
49334d8a380SJack Steiner 
49434d8a380SJack Steiner /*
49534d8a380SJack Steiner  * Convert a processor pagesize into the strange encoded pagesize used by the
49634d8a380SJack Steiner  * GRU. Processor pagesize is encoded as log of bytes per page. (or PAGE_SHIFT)
49734d8a380SJack Steiner  * 	pagesize	log pagesize	grupagesize
49834d8a380SJack Steiner  * 	  4k			12	0
49934d8a380SJack Steiner  * 	 16k 			14	1
50034d8a380SJack Steiner  * 	 64k			16	2
50134d8a380SJack Steiner  * 	256k			18	3
50234d8a380SJack Steiner  * 	  1m			20	4
50334d8a380SJack Steiner  * 	  2m			21	5
50434d8a380SJack Steiner  * 	  4m			22	6
50534d8a380SJack Steiner  * 	 16m			24	7
50634d8a380SJack Steiner  * 	 64m			26	8
50734d8a380SJack Steiner  * 	...
50834d8a380SJack Steiner  */
50934d8a380SJack Steiner #define GRU_PAGESIZE(sh)	((((sh) > 20 ? (sh) + 2 : (sh)) >> 1) - 6)
51034d8a380SJack Steiner #define GRU_SIZEAVAIL(sh)	(1UL << GRU_PAGESIZE(sh))
51134d8a380SJack Steiner 
51234d8a380SJack Steiner /* minimum TLB purge count to ensure a full purge */
51334d8a380SJack Steiner #define GRUMAXINVAL		1024UL
51434d8a380SJack Steiner 
5156e910074SJack Steiner int cch_allocate(struct gru_context_configuration_handle *cch);
516a24e5e1cSJack Steiner int cch_start(struct gru_context_configuration_handle *cch);
517a24e5e1cSJack Steiner int cch_interrupt(struct gru_context_configuration_handle *cch);
518a24e5e1cSJack Steiner int cch_deallocate(struct gru_context_configuration_handle *cch);
519a24e5e1cSJack Steiner int cch_interrupt_sync(struct gru_context_configuration_handle *cch);
520a24e5e1cSJack Steiner int tgh_invalidate(struct gru_tlb_global_handle *tgh, unsigned long vaddr,
521a24e5e1cSJack Steiner 	unsigned long vaddrmask, int asid, int pagesize, int global, int n,
522a24e5e1cSJack Steiner 	unsigned short ctxbitmap);
523c550222fSJack Steiner int tfh_write_only(struct gru_tlb_fault_handle *tfh, unsigned long paddr,
524c550222fSJack Steiner 	int gaa, unsigned long vaddr, int asid, int dirty, int pagesize);
525a24e5e1cSJack Steiner void tfh_write_restart(struct gru_tlb_fault_handle *tfh, unsigned long paddr,
526a24e5e1cSJack Steiner 	int gaa, unsigned long vaddr, int asid, int dirty, int pagesize);
527a24e5e1cSJack Steiner void tfh_restart(struct gru_tlb_fault_handle *tfh);
528a24e5e1cSJack Steiner void tfh_user_polling_mode(struct gru_tlb_fault_handle *tfh);
529a24e5e1cSJack Steiner void tfh_exception(struct gru_tlb_fault_handle *tfh);
53034d8a380SJack Steiner 
53134d8a380SJack Steiner #endif /* __GRUHANDLES_H__ */
532