File: /usr/src/linux/include/asm-ia64/sn/ksys/l1.h
1 /* $Id$
2 *
3 * This file is subject to the terms and conditions of the GNU General Public
4 * License. See the file "COPYING" in the main directory of this archive
5 * for more details.
6 *
7 * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
8 * Copyright (C) 2000 by Colin Ngam
9 */
10
11 #ifndef _ASM_SN_KSYS_L1_H
12 #define _ASM_SN_KSYS_L1_H
13
14 #include <asm/sn/vector.h>
15 #include <asm/sn/addrs.h>
16 #include <asm/sn/sn1/bedrock.h>
17
18 #define BRL1_QSIZE 128 /* power of 2 is more efficient */
19 #define BRL1_BUFSZ 264 /* needs to be large enough
20 * to hold 2 flags, escaped
21 * CRC, type/subchannel byte,
22 * and escaped payload
23 */
24
25 #define BRL1_IQS 32
26 #define BRL1_OQS 4
27
28
29 typedef struct sc_cq_s {
30 u_char buf[BRL1_QSIZE];
31 int ipos, opos, tent_next;
32 } sc_cq_t;
33
34 /* An l1sc_t struct can be associated with the local (C-brick) L1 or an L1
35 * on an R-brick. In the R-brick case, the l1sc_t records a vector path
36 * to the R-brick's junk bus UART. In the C-brick case, we just use the
37 * following flag to denote the local uart.
38 *
39 * This value can't be confused with a network vector because the least-
40 * significant nibble of a network vector cannot be greater than 8.
41 */
42 #define BRL1_LOCALUART ((net_vec_t)0xf)
43
44 /* L1<->Bedrock reserved subchannels */
45
46 /* console channels */
47 #define SC_CONS_CPU0 0x00
48 #define SC_CONS_CPU1 0x01
49 #define SC_CONS_CPU2 0x02
50 #define SC_CONS_CPU3 0x03
51
52 #define L1_ELSCUART_SUBCH(p) (p)
53 #define L1_ELSCUART_CPU(ch) (ch)
54
55 #define SC_CONS_SYSTEM CPUS_PER_NODE
56
57 /* mapping subchannels to queues */
58 #define MAP_IQ(s) (s)
59 #define MAP_OQ(s) (s)
60
61 #define BRL1_NUM_SUBCHANS 32
62 #define BRL1_CMD_SUBCH 16
63 #define BRL1_EVENT_SUBCH (BRL1_NUM_SUBCHANS - 1)
64 #define BRL1_SUBCH_RSVD 0
65 #define BRL1_SUBCH_FREE (-1)
66
67 /* constants for L1 hwgraph vertex info */
68 #define CBRICK_L1 (__psint_t)1
69 #define IOBRICK_L1 (__psint_t)2
70 #define RBRICK_L1 (__psint_t)3
71
72
73 struct l1sc_s;
74 typedef void (*brl1_notif_t)(struct l1sc_s *, int);
75 typedef int (*brl1_uartf_t)(struct l1sc_s *);
76
77 /* structure for controlling a subchannel */
78 typedef struct brl1_sch_s {
79 int use; /* if this subchannel is free,
80 * use == BRL1_SUBCH_FREE */
81 uint target; /* type, rack and slot of component to
82 * which this subchannel is directed */
83 atomic_t packet_arrived; /* true if packet arrived on
84 * this subchannel */
85 sc_cq_t * iqp; /* input queue for this subchannel */
86 sv_t arrive_sv; /* used to wait for a packet */
87 spinlock_t data_lock; /* synchronize access to input queues and
88 * other fields of the brl1_sch_s struct */
89 brl1_notif_t tx_notify; /* notify higher layer that transmission may
90 * continue */
91 brl1_notif_t rx_notify; /* notify higher layer that a packet has been
92 * received */
93 } brl1_sch_t;
94
95 /* br<->l1 protocol states */
96 #define BRL1_IDLE 0
97 #define BRL1_FLAG 1
98 #define BRL1_HDR 2
99 #define BRL1_BODY 3
100 #define BRL1_ESC 4
101 #define BRL1_RESET 7
102
103
104 #ifndef _LANGUAGE_ASSEMBLY
105
106 /*
107 * l1sc_t structure-- tracks protocol state, open subchannels, etc.
108 */
109 typedef struct l1sc_s {
110 nasid_t nasid; /* nasid with which this instance
111 * of the structure is associated */
112 moduleid_t modid; /* module id of this brick */
113 u_char verbose; /* non-zero if elscuart routines should
114 * prefix output */
115 net_vec_t uart; /* vector path to UART, or BRL1_LOCALUART */
116 int sent; /* number of characters sent */
117 int send_len; /* number of characters in send buf */
118 brl1_uartf_t putc_f; /* pointer to UART putc function */
119 brl1_uartf_t getc_f; /* pointer to UART getc function */
120
121 spinlock_t subch_lock; /* arbitrates subchannel allocation */
122 cpuid_t intr_cpu; /* cpu that receives L1 interrupts */
123
124 u_char send_in_use; /* non-zero if send buffer contains an
125 * unsent or partially-sent packet */
126 u_char fifo_space; /* current depth of UART send FIFO */
127
128 u_char brl1_state; /* current state of the receive side */
129 u_char brl1_last_hdr; /* last header byte received */
130
131 char send[BRL1_BUFSZ]; /* send buffer */
132
133 int sol; /* "start of line" (see elscuart routines) */
134 int cons_listen; /* non-zero if the elscuart interface should
135 * also check the system console subchannel */
136 brl1_sch_t subch[BRL1_NUM_SUBCHANS];
137 /* subchannels provided by link */
138
139 sc_cq_t garbage_q; /* a place to put unsolicited packets */
140 sc_cq_t oq[BRL1_OQS]; /* elscuart output queues */
141
142 } l1sc_t;
143
144
145 /* error codes */
146 #define BRL1_VALID 0
147 #define BRL1_FULL_Q (-1)
148 #define BRL1_CRC (-2)
149 #define BRL1_PROTOCOL (-3)
150 #define BRL1_NO_MESSAGE (-4)
151 #define BRL1_LINK (-5)
152 #define BRL1_BUSY (-6)
153
154 #define SC_SUCCESS BRL1_VALID
155 #define SC_NMSG BRL1_NO_MESSAGE
156 #define SC_BUSY BRL1_BUSY
157 #define SC_NOPEN (-7)
158 #define SC_BADSUBCH (-8)
159 #define SC_TIMEDOUT (-9)
160 #define SC_NSUBCH (-10)
161
162
163 /* L1 Target Addresses */
164 /*
165 * L1 commands and responses use source/target addresses that are
166 * 32 bits long. These are broken up into multiple bitfields that
167 * specify the type of the target controller (could actually be L2
168 * L3, not just L1), the rack and bay of the target, and the task
169 * id (L1 functionality is divided into several independent "tasks"
170 * that can each receive command requests and transmit responses)
171 */
172 #define L1_ADDR_TYPE_SHFT 28
173 #define L1_ADDR_TYPE_MASK 0xF0000000
174 #define L1_ADDR_TYPE_L1 0x00 /* L1 system controller */
175 #define L1_ADDR_TYPE_L2 0x01 /* L2 system controller */
176 #define L1_ADDR_TYPE_L3 0x02 /* L3 system controller */
177 #define L1_ADDR_TYPE_CBRICK 0x03 /* attached C brick */
178 #define L1_ADDR_TYPE_IOBRICK 0x04 /* attached I/O brick */
179
180 #define L1_ADDR_RACK_SHFT 18
181 #define L1_ADDR_RACK_MASK 0x0FFC0000
182 #define L1_ADDR_RACK_LOCAL 0x3ff /* local brick's rack */
183
184 #define L1_ADDR_BAY_SHFT 12
185 #define L1_ADDR_BAY_MASK 0x0003F000
186 #define L1_ADDR_BAY_LOCAL 0x3f /* local brick's bay */
187
188 #define L1_ADDR_TASK_SHFT 0
189 #define L1_ADDR_TASK_MASK 0x0000001F
190 #define L1_ADDR_TASK_INVALID 0x00 /* invalid task */
191 #define L1_ADDR_TASK_IROUTER 0x01 /* iRouter */
192 #define L1_ADDR_TASK_SYS_MGMT 0x02 /* system management port */
193 #define L1_ADDR_TASK_CMD 0x03 /* command interpreter */
194 #define L1_ADDR_TASK_ENV 0x04 /* environmental monitor */
195 #define L1_ADDR_TASK_BEDROCK 0x05 /* bedrock */
196 #define L1_ADDR_TASK_GENERAL 0x06 /* general requests */
197
198 #define L1_ADDR_LOCAL \
199 (L1_ADDR_TYPE_L1 << L1_ADDR_TYPE_SHFT) | \
200 (L1_ADDR_RACK_LOCAL << L1_ADDR_RACK_SHFT) | \
201 (L1_ADDR_BAY_LOCAL << L1_ADDR_BAY_SHFT)
202
203 #define L1_ADDR_LOCALIO \
204 (L1_ADDR_TYPE_IOBRICK << L1_ADDR_TYPE_SHFT) | \
205 (L1_ADDR_RACK_LOCAL << L1_ADDR_RACK_SHFT) | \
206 (L1_ADDR_BAY_LOCAL << L1_ADDR_BAY_SHFT)
207
208 #define L1_ADDR_LOCAL_SHFT L1_ADDR_BAY_SHFT
209
210 /* response argument types */
211 #define L1_ARG_INT 0x00 /* 4-byte integer (big-endian) */
212 #define L1_ARG_ASCII 0x01 /* null-terminated ASCII string */
213 #define L1_ARG_UNKNOWN 0x80 /* unknown data type. The low
214 * 7 bits will contain the data
215 * length. */
216
217 /* response codes */
218 #define L1_RESP_OK 0 /* no problems encountered */
219 #define L1_RESP_IROUTER (- 1) /* iRouter error */
220 #define L1_RESP_ARGC (-100) /* arg count mismatch */
221 #define L1_RESP_REQC (-101) /* bad request code */
222 #define L1_RESP_NAVAIL (-104) /* requested data not available */
223 #define L1_RESP_ARGVAL (-105) /* arg value out of range */
224 #define L1_RESP_INVAL (-107) /* requested data invalid */
225
226 /* L1 general requests */
227
228 /* request codes */
229 #define L1_REQ_RDBG 0x0001 /* read debug switches */
230 #define L1_REQ_RRACK 0x0002 /* read brick rack & bay */
231 #define L1_REQ_RRBT 0x0003 /* read brick rack, bay & type */
232 #define L1_REQ_SER_NUM 0x0004 /* read brick serial number */
233 #define L1_REQ_FW_REV 0x0005 /* read L1 firmware revision */
234 #define L1_REQ_EEPROM 0x0006 /* read EEPROM info */
235 #define L1_REQ_EEPROM_FMT 0x0007 /* get EEPROM data format & size */
236 #define L1_REQ_SYS_SERIAL 0x0008 /* read system serial number */
237 #define L1_REQ_PARTITION_GET 0x0009 /* read partition id */
238 #define L1_REQ_PORTSPEED 0x000a /* get ioport speed */
239
240 #define L1_REQ_CONS_SUBCH 0x1002 /* select this node's console
241 subchannel */
242 #define L1_REQ_CONS_NODE 0x1003 /* volunteer to be the master
243 (console-hosting) node */
244 #define L1_REQ_DISP1 0x1004 /* write line 1 of L1 display */
245 #define L1_REQ_DISP2 0x1005 /* write line 2 of L1 display */
246 #define L1_REQ_PARTITION_SET 0x1006 /* set partition id */
247 #define L1_REQ_EVENT_SUBCH 0x1007 /* set the subchannel for system
248 controller event transmission */
249
250 #define L1_REQ_RESET 0x2000 /* request a full system reset */
251 #define L1_REQ_PCI_UP 0x2001 /* power up pci slot or bus */
252 #define L1_REQ_PCI_DOWN 0x2002 /* power down pci slot or bus */
253 #define L1_REQ_PCI_RESET 0x2003 /* reset pci bus or slot */
254
255 /* L1 command interpreter requests */
256
257 /* request codes */
258 #define L1_REQ_EXEC_CMD 0x0000 /* interpret and execute an ASCII
259 command string */
260
261
262 /* brick type response codes */
263 #define L1_BRICKTYPE_C 0x43
264 #define L1_BRICKTYPE_I 0x49
265 #define L1_BRICKTYPE_P 0x50
266 #define L1_BRICKTYPE_R 0x52
267 #define L1_BRICKTYPE_X 0x58
268
269 /* EEPROM codes (for the "read EEPROM" request) */
270 /* c brick */
271 #define L1_EEP_NODE 0x00 /* node board */
272 #define L1_EEP_PIMM0 0x01
273 #define L1_EEP_PIMM(x) (L1_EEP_PIMM0+(x))
274 #define L1_EEP_DIMM0 0x03
275 #define L1_EEP_DIMM(x) (L1_EEP_DIMM0+(x))
276
277 /* other brick types */
278 #define L1_EEP_POWER 0x00 /* power board */
279 #define L1_EEP_LOGIC 0x01 /* logic board */
280
281 /* info area types */
282 #define L1_EEP_CHASSIS 1 /* chassis info area */
283 #define L1_EEP_BOARD 2 /* board info area */
284 #define L1_EEP_IUSE 3 /* internal use area */
285 #define L1_EEP_SPD 4 /* serial presence detect record */
286
287 typedef uint32_t l1addr_t;
288
289 #define L1_BUILD_ADDR(addr,at,r,s,t) \
290 (*(l1addr_t *)(addr) = ((l1addr_t)(at) << L1_ADDR_TYPE_SHFT) | \
291 ((l1addr_t)(r) << L1_ADDR_RACK_SHFT) | \
292 ((l1addr_t)(s) << L1_ADDR_BAY_SHFT) | \
293 ((l1addr_t)(t) << L1_ADDR_TASK_SHFT))
294
295 #define L1_ADDRESS_TO_TASK(addr,trb,tsk) \
296 (*(l1addr_t *)(addr) = (l1addr_t)(trb) | \
297 ((l1addr_t)(tsk) << L1_ADDR_TASK_SHFT))
298
299
300 #define L1_DISPLAY_LINE_LENGTH 12 /* L1 display characters/line */
301
302 #ifdef L1_DISP_2LINES
303 #define L1_DISPLAY_LINES 2 /* number of L1 display lines */
304 #else
305 #define L1_DISPLAY_LINES 1 /* number of L1 display lines available
306 * to system software */
307 #endif
308
309 #define SC_EVENT_CLASS_MASK ((unsigned short)0xff00)
310
311 #define bzero(d, n) memset((d), 0, (n))
312
313 /* public interfaces to L1 system controller */
314
315 int sc_open( l1sc_t *sc, uint target );
316 int sc_close( l1sc_t *sc, int ch );
317 int sc_construct_msg( l1sc_t *sc, int ch,
318 char *msg, int msg_len,
319 uint addr_task, short req_code,
320 int req_nargs, ... );
321 int sc_interpret_resp( char *resp, int resp_nargs, ... );
322 int sc_send( l1sc_t *sc, int ch, char *msg, int len, int wait );
323 int sc_recv( l1sc_t *sc, int ch, char *msg, int *len, uint64_t block );
324 int sc_command( l1sc_t *sc, int ch, char *cmd, char *resp, int *len );
325 int sc_command_kern( l1sc_t *sc, int ch, char *cmd, char *resp, int *len );
326 int sc_poll( l1sc_t *sc, int ch );
327 void sc_init( l1sc_t *sc, nasid_t nasid, net_vec_t uart );
328 void sc_intr_enable( l1sc_t *sc );
329
330 int _elscuart_putc( l1sc_t *sc, int c );
331 int _elscuart_getc( l1sc_t *sc );
332 int _elscuart_poll( l1sc_t *sc );
333 int _elscuart_readc( l1sc_t *sc );
334 int _elscuart_flush( l1sc_t *sc );
335 int _elscuart_probe( l1sc_t *sc );
336 void _elscuart_init( l1sc_t *sc );
337 void elscuart_syscon_listen( l1sc_t *sc );
338
339 int elsc_rack_bay_get(l1sc_t *e, uint *rack, uint *bay);
340 int elsc_rack_bay_type_get(l1sc_t *e, uint *rack,
341 uint *bay, uint *brick_type);
342 int elsc_cons_subch(l1sc_t *e, uint ch);
343 int elsc_cons_node(l1sc_t *e);
344 int elsc_display_line(l1sc_t *e, char *line, int lnum);
345
346 extern l1sc_t *get_elsc( void );
347 #define get_l1sc get_elsc
348 #define get_master_l1sc get_l1sc
349
350 int router_module_get( nasid_t nasid, net_vec_t path );
351
352 int iobrick_rack_bay_type_get( l1sc_t *sc, uint *rack,
353 uint *bay, uint *brick_type );
354 int iobrick_module_get( l1sc_t *sc );
355 int iobrick_pci_slot_pwr( l1sc_t *sc, int bus, int slot, int up );
356 int iobrick_pci_bus_pwr( l1sc_t *sc, int bus, int up );
357 int iobrick_sc_version( l1sc_t *sc, char *result );
358
359
360 #endif /* !_LANGUAGE_ASSEMBLY */
361 #endif /* _ASM_SN_KSYS_L1_H */
362