xref: /titanic_52/usr/src/uts/sun4u/starfire/sys/cpu_sgn.h (revision 6185db853e024a486ff8837e6784dd290d866112)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright (c) 2000 by Sun Microsystems, Inc.
24  * All rights reserved.
25  */
26 
27 #ifndef	_CPU_SGN_H
28 #define	_CPU_SGN_H
29 
30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35 
36 #ifndef _ASM
37 #include <sys/types.h>
38 #include <sys/cpuvar.h>
39 #endif /* _ASM */
40 
41 /*
42  * BBSRAM virtual address - 64 bits max.
43  */
44 typedef uint64_t vaddr_t;
45 
46 /*
47  * Special type for BBSRAM offsets (rather than pointers).
48  * This must be a 32 bit value
49  */
50 typedef uint32_t bboff_t;
51 
52 /*
53  *  As long as each component of the revision is less than
54  *  256, this trick will work.  So we check for that and generate a
55  *  syntax error if the SID is out of range.
56  */
57 #define	SIGB_MBOX_SIZE  64
58 /* reserved space - rounds size of sigblock_t to 512 */
59 #define	SIGB_RESV	16
60 
61 #define	BASE_ADDR_T_OFFSET	0xFE0	/* BBSRAM base_addr_t offset */
62 
63 #define	CVC_OUT_SIZ		1024	/* cvc output buffer size */
64 #define	CVC_IN_SIZ		256	/* cvc input buffer size */
65 
66 /* make sure the assembler doesn't see the C code */
67 #ifndef _ASM
68 
69 /*
70  * The reserved hardware interrupt 7F is used as a pointer structure
71  * to the two processors' signature blocks in bbsram. Each trap entry
72  * is 32 bytes, so this structure is always present at bbsram offset
73  * 0xFE0.
74  * Over time, we may discover other items that need pointers, that don't
75  * logically fit in the sigblocks themselves. This structure declares
76  * the global use of these 8 words.
77  * The spare_x words are reserved in case a design change calls for
78  * using 64-bit virtual addresses instead of offsets. This is
79  * considered unlikely.
80  *
81  * The offsets and this structure are normally created by POST when it
82  * initially creates the sigblocks. Subsequent programs  may move the
83  * sigblocks in bbsram as they see fit, as long as this structure is changed
84  * to reflect the new location.
85  */
86 
87 typedef struct {
88 	bboff_t sigblk_offset_0;	/* BBSRAM sig block 0 offset */
89 	uint32_t spare_0;		/* spare word just in case */
90 	bboff_t sigblk_offset_1;	/* BBSRAM sig block 1 offset */
91 	uint32_t spare_1;		/* another just in case */
92 	uint32_t pad[4];		/* trap is 8 32-bit words long */
93 } base_addr_t;
94 
95 
96 /*
97  * The following are used in the flag field of the mailbox structure.
98  * They are used to synchronize access with the mailbox between the
99  * SSP and Host, and indicate direction of the given message.
100  */
101 #define	SIGB_MBOX_EMPTY	0
102 #define	SIGB_MBOX_BUSY	1
103 #define	HOST_TO_CBS	2
104 #define	CBS_TO_HOST	3
105 
106 /* for sigblk polling */
107 #define	SIGB_INTR_OFF	0x00
108 #define	SIGB_INTR_SEND	0xFF
109 
110 typedef	short	mboxflag_t;
111 
112 /*
113  *  BE CAREFUL with modifications. To optimize transfers on the
114  *  bootbus between the kernel and mailbox, try to make sure the data
115  *  field falls on a 16 byte boundary.
116  */
117 typedef struct {
118 /*  0 */	short		intr;
119 /*  2 */	mboxflag_t	flag;
120 /*  4 */	int32_t		len;
121 /*  8 */	uint32_t	cmd;
122 /*  c */	char		data[SIGB_MBOX_SIZE];
123 } sigbmbox_t;	/* sizeof = 76 (0x4c) = 19X */
124 
125 typedef struct {
126 	uchar_t	cvc_output_buf[CVC_OUT_SIZ];
127 	uchar_t	cvc_input_buf[CVC_IN_SIZ];
128 	uchar_t cvc_obp_input_flag;	/* !=0 -> OBP wants CVC input */
129 } sigb_cvc_t;
130 
131 /*
132  * Every CPU signature, state, or substate transition is captured
133  * in the ring buffer. OS or OBP will be the writer of the ring buffer
134  * and control board executive (via JTAG) will be the sole reader. Because of
135  * space limitation in the BBSRAM, the ring buffer can only be 64 entries big.
136  * A ring buffer is necessary because of the speed difference between the
137  * reader and writer, and to prevent race condition.
138  *
139  * The ring buffer structure contains two pointers, one for reading and
140  * one for writing, and the buffer itself. The last 6 bits in each of the
141  * pointer identify an entry in the buffer. The read pointer represents
142  * the next entry the reader should read. The write pointer represents the
143  * next entry the writer is going to write. For the reader, the ring buffer
144  * contains un-read entries if the read and write pointers are different.
145  *
146  * In most situations, the reader should be able to keep up with the
147  * writer. However, in the case where the writer is transitioning
148  * rapidly, the reader may not be able to keep up and causes an overflow.
149  * When an overflow happens, instead of suspending the writer, the
150  * writer continues to write.
151  *
152  * The first transition that causes an overflow has 2 consequences
153  * because of this continuous write action:
154  * 1. The ring buffer is flushed, all previous transitions history are lost.
155  *
156  * Flushing the ring buffer is acceptable since the reader is not
157  * able to keep up with rapid transitions, it is better off to start
158  * from the current transition than trying to catch up.
159  *
160  * 2. The new transition is recorded in the ring buffer. However, bcecause of
161  *    the way the write pointer is updated, both the read and write pointers
162  *    will be identical which makes the reader thinks there is no transition to
163  *    read.
164  *
165  * Even though the reader does not see the most current signature/state in the
166  * ring buffer, it can be found in the signature block data structure.
167  * The reader can do a read in the signature block to obtain the current
168  * signature/block if the read/write pointers indicate the buffer is empty.
169  * The problem will go away once the writer starts writing again.
170  *
171  * Initial condition:
172  * rd_ptr = 0
173  * wr_ptr = 0
174  *
175  * To write a signature into the ring buffer, the steps are:
176  * 1. write signature into ringbuf[wr_ptr]
177  * 2. increment wr_ptr by 1 modulo SIGB_RB_SIZ using RB_IDX_MASK
178  *
179  * Note: the writer always writes to the ring buffer and the signature
180  * field in the signature block data structure.
181  *
182  * To read a signature from the ring buffer, the steps are:
183  * 1. compare rd_ptr and wr_ptr
184  * 2. if they are not equal then
185  *    	read signature ringbuf[rd_ptr]
186  *    	increment rd_ptr by 1 modulo SIGB_RB_SIZ using RB_IDX_MASK
187  *	save a copy of the signature locally
188  *	return the signature
189  * 3. else
190  * 	read signature from the signature block data structure
191  * 	if signature is not the same as the last signature then
192  *		return the signature
193  *
194  */
195 
196 #define	SIGB_RB_SIZ	64		/* ring buffer size */
197 #define	RB_IDX_MASK	0x3f		/* mask to determine read/write index */
198 
199 typedef struct {
200 /*  0 */	uchar_t		rd_ptr;		/* entry to read */
201 /*  1 */	uchar_t		wr_ptr;		/* next entry to write */
202 /*  4 */	sig_state_t	ringbuf[SIGB_RB_SIZ];
203 } sigb_ringbuf_t;	/* sizeof = 260 (0x104) = 65X */
204 
205 typedef struct cpu_sgnblk {
206 /*  0 */	uint32_t	sigb_magic;	/* SIGBLOCK_MAGIC */
207 /*  4 */	uint32_t	sigb_version;	/* changes with each SID */
208 /*  8 */	uint32_t	sigb_flags;	/* struct sigblock status */
209 /*  c */	uint32_t	sigb_heartbeat; /* prog's heartbeat */
210 
211 /* 10 */	uint32_t	sigb_leds;	/* Software LED */
212 /* 14 */	sig_state_t	sigb_signature; /* Current signature & state */
213 
214 	/*
215 	 * sigb_ringbuf captures the last SIGB_RB_SIZ signature/state
216 	 * transitions.
217 	 */
218 /* 18 */	sigb_ringbuf_t	sigb_ringbuf;
219 
220 	/*
221 	 * sigb_host_mbox is intended for msgs targeted for the Host and
222 	 * follows the protocol:
223 	 *   SSP -> [cmd] -> Host -> [resp] -> SSP.
224 	 */
225 /* 11c */	sigbmbox_t	sigb_host_mbox;
226 
227 /* 168 */	char	sigb_idn[sizeof (sigbmbox_t)];
228 
229 /* 1b4 */	bboff_t	sigb_obp_mbox;	/* OBP/DHLP mailbox. */
230 
231 /* 1b8 */	bboff_t	sigb_postconfig; /* config info from POST */
232 
233 /* 1bc */	uint32_t	sigb_post;	/* POST opaque */
234 
235 /* 1c0 */	bboff_t	sigb_slavep;	/* Slave startup block offset */
236 
237 /* 1c4 */	bboff_t	sigb_resetinfo_off;	/* Resetinfo offset */
238 
239 /* 1c8 */	bboff_t	sigb_cvc_off;	/* CVC offset */
240 
241 /* 1cc */	bboff_t	sigb_eeprom_off;	/* EEPROM offset */
242 
243 /* 1d0 */	vaddr_t	sigb_wdog_reset_vec; /* Watchdog Reset Vector */
244 
245 /* 1d8 */	vaddr_t	sigb_xir_reset_vec;	/* XIR Reset vector */
246 
247 /* 1e0 */	vaddr_t	sigb_sir_reset_vec;	/* SIR Reset Vector */
248 
249 /* 1e8 */	vaddr_t	sigb_red_state_reset_vec;   /* RED State Reset Vector */
250 
251 /* 1f0 */	uchar_t	sigb_resv_array[SIGB_RESV]; /* reserved space */
252 } cpu_sgnblk_t;	/* sizeof = 512 (0x200) = 128X */
253 
254 #endif /* _ASM */
255 
256 /*
257  * Mailbox commands.
258  *
259  * The commands are listed here so that they are in a central place
260  * for all users of the signature block mailbox.  Want to be careful
261  * that some subsystems don't accidently use the same value for a
262  * command.  For this reason we introduce a cookie for each subsystem.
263  */
264 
265 #define	SIGB_HANDLER_BUSY	(-2)
266 #define	SIGB_BAD_MBOX_CMD	(-1)
267 #define	SSP_CMD			('S' << 8)	/* generic SSP */
268 #define	SSP_CMD_SUCCESS		(SSP_CMD | 0x1)
269 #define	SSP_GOTO_OBP		(SSP_CMD | 0x2)
270 #define	SSP_GOTO_PANIC		(SSP_CMD | 0x3)
271 #define	SSP_ENVIRON		(SSP_CMD | 0x4) /* environmental intr */
272 
273 #ifdef _KERNEL
274 
275 #ifdef _STARFIRE
276 
277 extern void juggle_sgnblk_poll(struct cpu *);
278 extern int sgnblk_poll_register(void (*)(processorid_t, cpu_sgnblk_t *));
279 extern int sgnblk_poll_unregister(void (*)(processorid_t, cpu_sgnblk_t *));
280 extern int sgnblk_poll_reference(void (*)(cpu_sgnblk_t *, void *), void *);
281 extern void sgnblk_poll_unreference(void (*)(cpu_sgnblk_t *, void *));
282 
283 extern cpu_sgnblk_t *cpu_sgnblkp[NCPU];
284 
285 /*
286  *  Starfire specific signatures
287  */
288 #define	POST_SIG	SIG_BLD('P', 'O')
289 #define	DHLP_SIG	SIG_BLD('D', 'H')
290 
291 /*
292  *  Starfire specific Sigblock states.
293  */
294 #define	SIGBST_NONE	0	/* no state */
295 #define	SIGBST_RUN	1	/* running */
296 #define	SIGBST_EXIT	2	/* finished */
297 #define	SIGBST_PRERUN	3	/* pre-exec */
298 #define	SIGBST_ARBSTOP	4	/* transient arbstop state */
299 #define	SIGBST_RESET	5	/* reset */
300 #define	SIGBST_POWEROFF	6	/* no power */
301 #define	SIGBST_DETACHED	7	/* spinning in OBP after DR DETACH */
302 #define	SIGBST_CALLBACK	8	/* kernel calling back into OBP */
303 #define	SIGBST_WATCHDOG	9	/* OBP running after watchdog */
304 #define	SIGBST_WATCHDOG_SYNC	10 /* OBP "sync" after watchdog reset */
305 #define	SIGBST_OFFLINE	11	/* cpu offline */
306 #define	SIGBST_BOOTING	12	/* booting */
307 #define	SIGBST_UNKNOWN	13	/* unknown */
308 #define	SIGBST_XIR	14	/* OBP running after XIR */
309 #define	SIGBST_XIR_SYNC	15	/* OBP trying "sync" in XIR */
310 #define	SIGBST_SIR	16	/* OBP running after SIR */
311 #define	SIGBST_SIR_SYNC	17	/* OBP trying "sync" in SIR */
312 #define	SIGBST_REDMODE	18	/* OBP running after REDMODE */
313 #define	SIGBST_REDMODE_SYNC	19	/* OBP trying "sync" in REDMODE */
314 #define	SIGBST_QUIESCED		20	/* system quiesced */
315 #define	SIGBST_QUIESCE_INPROGRESS 21	/* system quiesce in-progress */
316 #define	SIGBST_RESUME_INPROGRESS 22	/* system resume in-progress */
317 
318 /*
319  *  Starfire specific Sigblock sub-states
320  */
321 #define	EXIT_NULL		0
322 #define	EXIT_HALT		1
323 #define	EXIT_ENVIRON		2
324 #define	EXIT_REBOOT		3
325 #define	EXIT_PANIC1		4
326 #define	EXIT_PANIC2		5
327 #define	EXIT_HUNG		6
328 #define	EXIT_WATCH		7
329 #define	EXIT_PANIC_REBOOT	8
330 #define	EXIT_WATCHDOG_REBOOT	9
331 #define	EXIT_SOFT_INIT_RESET	10   /* SIR */
332 #define	EXIT_EXTERN_INIT_RESET	11   /* XIR */
333 #define	EXIT_REDMODE_REBOOT	12   /* REDMODE */
334 #define	EXIT_OBP_RESET		13   /* OBP RESET */
335 
336 #else
337 
338 #define	REGISTER_BBUS_INTR()
339 #define	CPU_SGN_MAPIN(cpuid)
340 #define	CPU_SGN_MAPOUT(cpuid)
341 #define	CPU_SGN_EXISTS(cpuid)	(0)
342 #define	SGN_CPU_IS_OS(cpuid)	(0)
343 #define	SGN_CPU_IS_OBP(cpuid)	(0)
344 #define	SGN_CPU_STATE_IS_DETACHED(cpuid)	(0)
345 
346 #endif	/* _STARFIRE */
347 
348 #endif	/* _KERNEL */
349 
350 #ifdef	__cplusplus
351 }
352 #endif
353 
354 #endif	/* _CPU_SGN_H */
355