aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-ia64/sn/ksys/l1.h
blob: d3f1be0655470ca634c7f62058d265e8281b4ae5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
/* $Id$
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
 */

#ifndef _ASM_SN_KSYS_L1_H
#define _ASM_SN_KSYS_L1_H

#include <linux/config.h>
#include <asm/sn/vector.h>
#include <asm/sn/addrs.h>
#include <asm/atomic.h>
#include <asm/sn/sv.h>


#ifdef CONFIG_IA64_SGI_SN1

#define BRL1_QSIZE	128	/* power of 2 is more efficient */
#define BRL1_BUFSZ	264	/* needs to be large enough
				 * to hold 2 flags, escaped
				 * CRC, type/subchannel byte,
				 * and escaped payload
				 */

#define BRL1_IQS          32
#define BRL1_OQS          4


typedef struct sc_cq_s {
    u_char              buf[BRL1_QSIZE];
    int                 ipos, opos, tent_next;
} sc_cq_t;

/* An l1sc_t struct can be associated with the local (C-brick) L1 or an L1
 * on an R-brick.  In the R-brick case, the l1sc_t records a vector path
 * to the R-brick's junk bus UART.  In the C-brick case, we just use the
 * following flag to denote the local uart.
 *
 * This value can't be confused with a network vector because the least-
 * significant nibble of a network vector cannot be greater than 8.
 */
#define BRL1_LOCALHUB_UART	((net_vec_t)0xf)

/* L1<->Bedrock reserved subchannels */

/* console channels */
#define SC_CONS_CPU0    0x00
#define SC_CONS_CPU1    0x01
#define SC_CONS_CPU2    0x02
#define SC_CONS_CPU3    0x03

#define L1_ELSCUART_SUBCH(p)	(p)
#define L1_ELSCUART_CPU(ch)	(ch)

#define SC_CONS_SYSTEM  CPUS_PER_NODE

/* mapping subchannels to queues */
#define MAP_IQ(s)       (s)
#define MAP_OQ(s)       (s)
     
#define BRL1_NUM_SUBCHANS 32
#define BRL1_CMD_SUBCH	  16
#define BRL1_EVENT_SUBCH  (BRL1_NUM_SUBCHANS - 1)
#define BRL1_SUBCH_RSVD   0
#define BRL1_SUBCH_FREE   (-1)

/* constants for L1 hwgraph vertex info */
#define CBRICK_L1	(__psint_t)1
#define IOBRICK_L1	(__psint_t)2
#define RBRICK_L1	(__psint_t)3


struct l1sc_s;     
/* Saved off interrupt frame */
typedef struct brl1_intr_frame {
	int bf_irq;		/* irq received */
	void *bf_dev_id;	/* device information */
	struct pt_regs *bf_regs; /* register frame */
} brl1_intr_frame_t;

typedef void (*brl1_notif_t)(int, void *, struct pt_regs *, struct l1sc_s *, int);
typedef int  (*brl1_uartf_t)(struct l1sc_s *);

/* structure for controlling a subchannel */
typedef struct brl1_sch_s {
    int		use;		/* if this subchannel is free,
				 * use == BRL1_SUBCH_FREE */
    uint	target;		/* type, rack and slot of component to
				 * which this subchannel is directed */
    atomic_t	packet_arrived; /* true if packet arrived on
				 * this subchannel */
    sc_cq_t *	iqp;		/* input queue for this subchannel */
    sv_t	arrive_sv;	/* used to wait for a packet */
    spinlock_t	data_lock;	/* synchronize access to input queues and
				 * other fields of the brl1_sch_s struct */
    brl1_notif_t tx_notify;     /* notify higher layer that transmission may 
				 * continue */
    brl1_notif_t rx_notify;	/* notify higher layer that a packet has been
				 * received */
    brl1_intr_frame_t irq_frame; /* saved off irq information */
} brl1_sch_t;

/* br<->l1 protocol states */
#define BRL1_IDLE	0
#define BRL1_FLAG	1
#define BRL1_HDR	2
#define BRL1_BODY	3
#define BRL1_ESC	4
#define BRL1_RESET	7


/*
 * l1sc_t structure-- tracks protocol state, open subchannels, etc.
 */
typedef struct l1sc_s {
    nasid_t	 nasid;		/* nasid with which this instance
				 * of the structure is associated */
    moduleid_t	 modid;         /* module id of this brick */
    u_char	 verbose;	/* non-zero if elscuart routines should
				 * prefix output */
    net_vec_t    uart;		/* vector path to UART, or BRL1_LOCALUART */
    int		 sent;		/* number of characters sent */
    int		 send_len;	/* number of characters in send buf */
    brl1_uartf_t putc_f;	/* pointer to UART putc function */
    brl1_uartf_t getc_f;	/* pointer to UART getc function */

    spinlock_t   send_lock;     /* arbitrates send synchronization */
    spinlock_t   recv_lock;     /* arbitrates uart receive access */
    spinlock_t	 subch_lock;	/* arbitrates subchannel allocation */
    cpuid_t	 intr_cpu;	/* cpu that receives L1 interrupts */

    u_char	 send_in_use;	/* non-zero if send buffer contains an
				 * unsent or partially-sent  packet */
    u_char	 fifo_space;	/* current depth of UART send FIFO */

    u_char	 brl1_state;	/* current state of the receive side */
    u_char	 brl1_last_hdr;	/* last header byte received */

    char	 send[BRL1_BUFSZ]; /* send buffer */

    int		 sol;		/* "start of line" (see elscuart routines) */
    int		 cons_listen;	/* non-zero if the elscuart interface should
				 * also check the system console subchannel */
    brl1_sch_t	 subch[BRL1_NUM_SUBCHANS];
    				/* subchannels provided by link */

    sc_cq_t	 garbage_q;	/* a place to put unsolicited packets */
    sc_cq_t	 oq[BRL1_OQS];	/* elscuart output queues */
} l1sc_t;


/* error codes */
#define BRL1_VALID	  0
#define BRL1_FULL_Q	(-1)
#define BRL1_CRC	(-2)
#define BRL1_PROTOCOL	(-3)
#define BRL1_NO_MESSAGE	(-4)
#define BRL1_LINK	(-5)
#define BRL1_BUSY	(-6)

#define SC_SUCCESS      BRL1_VALID
#define SC_NMSG         BRL1_NO_MESSAGE
#define SC_BUSY         BRL1_BUSY
#define SC_NOPEN        (-7)
#define SC_BADSUBCH     (-8)
#define SC_TIMEDOUT	(-9)
#define SC_NSUBCH	(-10)

#endif	/* CONFIG_IA64_SGI_SN1 */

/* L1 Target Addresses */
/*
 * L1 commands and responses use source/target addresses that are
 * 32 bits long.  These are broken up into multiple bitfields that
 * specify the type of the target controller (could actually be L2
 * L3, not just L1), the rack and bay of the target, and the task
 * id (L1 functionality is divided into several independent "tasks"
 * that can each receive command requests and transmit responses)
 */
#ifdef CONFIG_IA64_SGI_SN1
#define L1_ADDR_TYPE_SHFT	28
#define L1_ADDR_TYPE_MASK	0xF0000000
#else
#define L1_ADDR_TYPE_SHFT	8
#define L1_ADDR_TYPE_MASK	0xFF00
#endif	/* CONFIG_IA64_SGI_SN1 */
#define L1_ADDR_TYPE_L1		0x00	/* L1 system controller */
#define L1_ADDR_TYPE_L2		0x01	/* L2 system controller */
#define L1_ADDR_TYPE_L3		0x02	/* L3 system controller */
#define L1_ADDR_TYPE_CBRICK	0x03	/* attached C brick	*/
#define L1_ADDR_TYPE_IOBRICK	0x04	/* attached I/O brick	*/

#ifdef CONFIG_IA64_SGI_SN1
#define L1_ADDR_RACK_SHFT	18
#define L1_ADDR_RACK_MASK	0x0FFC0000
#define	L1_ADDR_RACK_LOCAL	0x3ff	/* local brick's rack	*/
#else
#define L1_ADDR_RACK_SHFT	16
#define L1_ADDR_RACK_MASK	0xFFFF00
#define	L1_ADDR_RACK_LOCAL	0xffff	/* local brick's rack	*/
#endif /* CONFIG_IA64_SGI_SN1 */

#ifdef CONFIG_IA64_SGI_SN1
#define L1_ADDR_BAY_SHFT	12
#define L1_ADDR_BAY_MASK	0x0003F000
#define	L1_ADDR_BAY_LOCAL	0x3f	/* local brick's bay	*/
#else
#define L1_ADDR_BAY_SHFT	0
#define L1_ADDR_BAY_MASK	0xFF
#define	L1_ADDR_BAY_LOCAL	0xff	/* local brick's bay	*/
#endif	/* CONFIG_IA64_SGI_SN1 */

#define L1_ADDR_TASK_SHFT	0
#define L1_ADDR_TASK_MASK	0x0000001F
#define L1_ADDR_TASK_INVALID	0x00	/* invalid task 	*/
#define	L1_ADDR_TASK_IROUTER	0x01	/* iRouter		*/
#define L1_ADDR_TASK_SYS_MGMT	0x02	/* system management port */
#define L1_ADDR_TASK_CMD	0x03	/* command interpreter	*/
#define L1_ADDR_TASK_ENV	0x04	/* environmental monitor */
#define L1_ADDR_TASK_BEDROCK	0x05	/* bedrock		*/
#define L1_ADDR_TASK_GENERAL	0x06	/* general requests	*/

#define L1_ADDR_LOCAL				\
    (L1_ADDR_TYPE_L1 << L1_ADDR_TYPE_SHFT) |	\
    (L1_ADDR_RACK_LOCAL << L1_ADDR_RACK_SHFT) |	\
    (L1_ADDR_BAY_LOCAL << L1_ADDR_BAY_SHFT)

#define L1_ADDR_LOCALIO					\
    (L1_ADDR_TYPE_IOBRICK << L1_ADDR_TYPE_SHFT) |	\
    (L1_ADDR_RACK_LOCAL << L1_ADDR_RACK_SHFT) |		\
    (L1_ADDR_BAY_LOCAL << L1_ADDR_BAY_SHFT)

#define L1_ADDR_LOCAL_SHFT	L1_ADDR_BAY_SHFT

/* response argument types */
#define L1_ARG_INT		0x00	/* 4-byte integer (big-endian)	*/
#define L1_ARG_ASCII		0x01	/* null-terminated ASCII string */
#define L1_ARG_UNKNOWN		0x80	/* unknown data type.  The low
					 * 7 bits will contain the data
					 * length.			*/

/* response codes */
#define L1_RESP_OK	    0	/* no problems encountered      */
#define L1_RESP_IROUTER	(-  1)	/* iRouter error	        */
#define L1_RESP_ARGC	(-100)	/* arg count mismatch	        */
#define L1_RESP_REQC	(-101)	/* bad request code	        */
#define L1_RESP_NAVAIL	(-104)	/* requested data not available */
#define L1_RESP_ARGVAL	(-105)  /* arg value out of range       */
#define L1_RESP_INVAL   (-107)  /* requested data invalid       */

/* L1 general requests */

/* request codes */
#define	L1_REQ_RDBG		0x0001	/* read debug switches	*/
#define L1_REQ_RRACK		0x0002	/* read brick rack & bay */
#define L1_REQ_RRBT		0x0003  /* read brick rack, bay & type */
#define L1_REQ_SER_NUM		0x0004  /* read brick serial number */
#define L1_REQ_FW_REV		0x0005  /* read L1 firmware revision */
#define L1_REQ_EEPROM		0x0006  /* read EEPROM info */
#define L1_REQ_EEPROM_FMT	0x0007  /* get EEPROM data format & size */
#define L1_REQ_SYS_SERIAL	0x0008	/* read system serial number */
#define L1_REQ_PARTITION_GET	0x0009	/* read partition id */
#define L1_REQ_PORTSPEED	0x000a	/* get ioport speed */

#define L1_REQ_CONS_SUBCH	0x1002  /* select this node's console 
					   subchannel */
#define L1_REQ_CONS_NODE	0x1003  /* volunteer to be the master 
					   (console-hosting) node */
#define L1_REQ_DISP1		0x1004  /* write line 1 of L1 display */
#define L1_REQ_DISP2		0x1005  /* write line 2 of L1 display */
#define L1_REQ_PARTITION_SET	0x1006	/* set partition id */
#define L1_REQ_EVENT_SUBCH	0x1007	/* set the subchannel for system
					   controller event transmission */

#define L1_REQ_RESET		0x2000	/* request a full system reset */
#define L1_REQ_PCI_UP		0x2001  /* power up pci slot or bus */
#define L1_REQ_PCI_DOWN		0x2002  /* power down pci slot or bus */
#define L1_REQ_PCI_RESET	0x2003  /* reset pci bus or slot */

/* L1 command interpreter requests */

/* request codes */
#define L1_REQ_EXEC_CMD		0x0000	/* interpret and execute an ASCII
					   command string */

/* brick type response codes */
#define L1_BRICKTYPE_IP45       0x34            /* 4 */
#define L1_BRICKTYPE_C          0x43            /* C */
#define L1_BRICKTYPE_I          0x49            /* I */
#define L1_BRICKTYPE_P          0x50            /* P */
#define L1_BRICKTYPE_R          0x52            /* R */
#define L1_BRICKTYPE_X          0x58            /* X */
#define L1_BRICKTYPE_X2         0x59            /* Y */
#define L1_BRICKTYPE_N          0x4e            /* N */
#define L1_BRICKTYPE_PX		0x23		/* # */

/* EEPROM codes (for the "read EEPROM" request) */
/* c brick */
#define L1_EEP_NODE		0x00	/* node board */
#define L1_EEP_PIMM0		0x01
#define L1_EEP_PIMM(x)		(L1_EEP_PIMM0+(x))
#define L1_EEP_DIMM0		0x03
#define L1_EEP_DIMM(x)		(L1_EEP_DIMM0+(x))

/* other brick types */
#define L1_EEP_POWER		0x00	/* power board */
#define L1_EEP_LOGIC		0x01	/* logic board */

/* info area types */
#define L1_EEP_CHASSIS		1	/* chassis info area */
#define L1_EEP_BOARD		2	/* board info area */
#define L1_EEP_IUSE		3	/* internal use area */
#define L1_EEP_SPD		4	/* serial presence detect record */

typedef uint32_t l1addr_t;

#define L1_BUILD_ADDR(addr,at,r,s,t)					\
    (*(l1addr_t *)(addr) = ((l1addr_t)(at) << L1_ADDR_TYPE_SHFT) |	\
			     ((l1addr_t)(r)  << L1_ADDR_RACK_SHFT) |	\
			     ((l1addr_t)(s)  << L1_ADDR_BAY_SHFT) |	\
			     ((l1addr_t)(t)  << L1_ADDR_TASK_SHFT))

#define L1_ADDRESS_TO_TASK(addr,trb,tsk)				\
    (*(l1addr_t *)(addr) = (l1addr_t)(trb) |				\
    			     ((l1addr_t)(tsk) << L1_ADDR_TASK_SHFT))

#define L1_DISPLAY_LINE_LENGTH	12	/* L1 display characters/line */

#ifdef L1_DISP_2LINES
#define L1_DISPLAY_LINES	2	/* number of L1 display lines */
#else
#define L1_DISPLAY_LINES	1	/* number of L1 display lines available
					 * to system software */
#endif

#define bzero(d, n)	memset((d), 0, (n))

#ifdef CONFIG_IA64_SGI_SN1

#define SC_EVENT_CLASS_MASK ((unsigned short)0xff00)

/* public interfaces to L1 system controller */

int	sc_open( l1sc_t *sc, uint target );
int	sc_close( l1sc_t *sc, int ch );
int	sc_construct_msg( l1sc_t *sc, int ch, 
			  char *msg, int msg_len,
			  uint addr_task, short req_code,
			  int req_nargs, ... );
int	sc_interpret_resp( char *resp, int resp_nargs, ... );
int	sc_send( l1sc_t *sc, int ch, char *msg, int len, int wait );
int	sc_recv( l1sc_t *sc, int ch, char *msg, int *len, uint64_t block );
int	sc_command( l1sc_t *sc, int ch, char *cmd, char *resp, int *len );
int	sc_command_kern( l1sc_t *sc, int ch, char *cmd, char *resp, int *len );
int	sc_poll( l1sc_t *sc, int ch );
void	sc_init( l1sc_t *sc, nasid_t nasid, net_vec_t uart );
void	sc_intr_enable( l1sc_t *sc );

int	elsc_rack_bay_get(l1sc_t *e, uint *rack, uint *bay);
int	elsc_rack_bay_type_get(l1sc_t *e, uint *rack, 
			       uint *bay, uint *brick_type);
int	elsc_cons_subch(l1sc_t *e, uint ch);
int	elsc_cons_node(l1sc_t *e);
int	elsc_display_line(l1sc_t *e, char *line, int lnum);

extern l1sc_t *get_elsc( void );
#define get_l1sc	get_elsc
#define get_master_l1sc get_l1sc

int	iobrick_rack_bay_type_get( l1sc_t *sc, uint *rack,
				   uint *bay, uint *brick_type );
int	iobrick_module_get( l1sc_t *sc );
int	iobrick_pci_slot_pwr( l1sc_t *sc, int bus, int slot, int up );
int	iobrick_pci_bus_pwr( l1sc_t *sc, int bus, int up );
int	iobrick_sc_version( l1sc_t *sc, char *result );
#else
int	elsc_display_line(nasid_t nasid, char *line, int lnum);
int	iobrick_rack_bay_type_get( nasid_t nasid, uint *rack,
				   uint *bay, uint *brick_type );
int	iobrick_module_get( nasid_t nasid );
#endif	/* CONFIG_IA64_SGI_SN1 */


#endif /* _ASM_SN_KSYS_L1_H */