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
|
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2000 by Sun Microsystems, Inc.
* All rights reserved.
*/
#ifndef _CPU_SGN_H
#define _CPU_SGN_H
#pragma ident "%Z%%M% %I% %E% SMI"
#ifdef __cplusplus
extern "C" {
#endif
#ifndef _ASM
#include <sys/types.h>
#include <sys/cpuvar.h>
#endif /* _ASM */
/*
* BBSRAM virtual address - 64 bits max.
*/
typedef uint64_t vaddr_t;
/*
* Special type for BBSRAM offsets (rather than pointers).
* This must be a 32 bit value
*/
typedef uint32_t bboff_t;
/*
* As long as each component of the revision is less than
* 256, this trick will work. So we check for that and generate a
* syntax error if the SID is out of range.
*/
#define SIGB_MBOX_SIZE 64
/* reserved space - rounds size of sigblock_t to 512 */
#define SIGB_RESV 16
#define BASE_ADDR_T_OFFSET 0xFE0 /* BBSRAM base_addr_t offset */
#define CVC_OUT_SIZ 1024 /* cvc output buffer size */
#define CVC_IN_SIZ 256 /* cvc input buffer size */
/* make sure the assembler doesn't see the C code */
#ifndef _ASM
/*
* The reserved hardware interrupt 7F is used as a pointer structure
* to the two processors' signature blocks in bbsram. Each trap entry
* is 32 bytes, so this structure is always present at bbsram offset
* 0xFE0.
* Over time, we may discover other items that need pointers, that don't
* logically fit in the sigblocks themselves. This structure declares
* the global use of these 8 words.
* The spare_x words are reserved in case a design change calls for
* using 64-bit virtual addresses instead of offsets. This is
* considered unlikely.
*
* The offsets and this structure are normally created by POST when it
* initially creates the sigblocks. Subsequent programs may move the
* sigblocks in bbsram as they see fit, as long as this structure is changed
* to reflect the new location.
*/
typedef struct {
bboff_t sigblk_offset_0; /* BBSRAM sig block 0 offset */
uint32_t spare_0; /* spare word just in case */
bboff_t sigblk_offset_1; /* BBSRAM sig block 1 offset */
uint32_t spare_1; /* another just in case */
uint32_t pad[4]; /* trap is 8 32-bit words long */
} base_addr_t;
/*
* The following are used in the flag field of the mailbox structure.
* They are used to synchronize access with the mailbox between the
* SSP and Host, and indicate direction of the given message.
*/
#define SIGB_MBOX_EMPTY 0
#define SIGB_MBOX_BUSY 1
#define HOST_TO_CBS 2
#define CBS_TO_HOST 3
/* for sigblk polling */
#define SIGB_INTR_OFF 0x00
#define SIGB_INTR_SEND 0xFF
typedef short mboxflag_t;
/*
* BE CAREFUL with modifications. To optimize transfers on the
* bootbus between the kernel and mailbox, try to make sure the data
* field falls on a 16 byte boundary.
*/
typedef struct {
/* 0 */ short intr;
/* 2 */ mboxflag_t flag;
/* 4 */ int32_t len;
/* 8 */ uint32_t cmd;
/* c */ char data[SIGB_MBOX_SIZE];
} sigbmbox_t; /* sizeof = 76 (0x4c) = 19X */
typedef struct {
uchar_t cvc_output_buf[CVC_OUT_SIZ];
uchar_t cvc_input_buf[CVC_IN_SIZ];
uchar_t cvc_obp_input_flag; /* !=0 -> OBP wants CVC input */
} sigb_cvc_t;
/*
* Every CPU signature, state, or substate transition is captured
* in the ring buffer. OS or OBP will be the writer of the ring buffer
* and control board executive (via JTAG) will be the sole reader. Because of
* space limitation in the BBSRAM, the ring buffer can only be 64 entries big.
* A ring buffer is necessary because of the speed difference between the
* reader and writer, and to prevent race condition.
*
* The ring buffer structure contains two pointers, one for reading and
* one for writing, and the buffer itself. The last 6 bits in each of the
* pointer identify an entry in the buffer. The read pointer represents
* the next entry the reader should read. The write pointer represents the
* next entry the writer is going to write. For the reader, the ring buffer
* contains un-read entries if the read and write pointers are different.
*
* In most situations, the reader should be able to keep up with the
* writer. However, in the case where the writer is transitioning
* rapidly, the reader may not be able to keep up and causes an overflow.
* When an overflow happens, instead of suspending the writer, the
* writer continues to write.
*
* The first transition that causes an overflow has 2 consequences
* because of this continuous write action:
* 1. The ring buffer is flushed, all previous transitions history are lost.
*
* Flushing the ring buffer is acceptable since the reader is not
* able to keep up with rapid transitions, it is better off to start
* from the current transition than trying to catch up.
*
* 2. The new transition is recorded in the ring buffer. However, bcecause of
* the way the write pointer is updated, both the read and write pointers
* will be identical which makes the reader thinks there is no transition to
* read.
*
* Even though the reader does not see the most current signature/state in the
* ring buffer, it can be found in the signature block data structure.
* The reader can do a read in the signature block to obtain the current
* signature/block if the read/write pointers indicate the buffer is empty.
* The problem will go away once the writer starts writing again.
*
* Initial condition:
* rd_ptr = 0
* wr_ptr = 0
*
* To write a signature into the ring buffer, the steps are:
* 1. write signature into ringbuf[wr_ptr]
* 2. increment wr_ptr by 1 modulo SIGB_RB_SIZ using RB_IDX_MASK
*
* Note: the writer always writes to the ring buffer and the signature
* field in the signature block data structure.
*
* To read a signature from the ring buffer, the steps are:
* 1. compare rd_ptr and wr_ptr
* 2. if they are not equal then
* read signature ringbuf[rd_ptr]
* increment rd_ptr by 1 modulo SIGB_RB_SIZ using RB_IDX_MASK
* save a copy of the signature locally
* return the signature
* 3. else
* read signature from the signature block data structure
* if signature is not the same as the last signature then
* return the signature
*
*/
#define SIGB_RB_SIZ 64 /* ring buffer size */
#define RB_IDX_MASK 0x3f /* mask to determine read/write index */
typedef struct {
/* 0 */ uchar_t rd_ptr; /* entry to read */
/* 1 */ uchar_t wr_ptr; /* next entry to write */
/* 4 */ sig_state_t ringbuf[SIGB_RB_SIZ];
} sigb_ringbuf_t; /* sizeof = 260 (0x104) = 65X */
typedef struct cpu_sgnblk {
/* 0 */ uint32_t sigb_magic; /* SIGBLOCK_MAGIC */
/* 4 */ uint32_t sigb_version; /* changes with each SID */
/* 8 */ uint32_t sigb_flags; /* struct sigblock status */
/* c */ uint32_t sigb_heartbeat; /* prog's heartbeat */
/* 10 */ uint32_t sigb_leds; /* Software LED */
/* 14 */ sig_state_t sigb_signature; /* Current signature & state */
/*
* sigb_ringbuf captures the last SIGB_RB_SIZ signature/state
* transitions.
*/
/* 18 */ sigb_ringbuf_t sigb_ringbuf;
/*
* sigb_host_mbox is intended for msgs targeted for the Host and
* follows the protocol:
* SSP -> [cmd] -> Host -> [resp] -> SSP.
*/
/* 11c */ sigbmbox_t sigb_host_mbox;
/* 168 */ char sigb_idn[sizeof (sigbmbox_t)];
/* 1b4 */ bboff_t sigb_obp_mbox; /* OBP/DHLP mailbox. */
/* 1b8 */ bboff_t sigb_postconfig; /* config info from POST */
/* 1bc */ uint32_t sigb_post; /* POST opaque */
/* 1c0 */ bboff_t sigb_slavep; /* Slave startup block offset */
/* 1c4 */ bboff_t sigb_resetinfo_off; /* Resetinfo offset */
/* 1c8 */ bboff_t sigb_cvc_off; /* CVC offset */
/* 1cc */ bboff_t sigb_eeprom_off; /* EEPROM offset */
/* 1d0 */ vaddr_t sigb_wdog_reset_vec; /* Watchdog Reset Vector */
/* 1d8 */ vaddr_t sigb_xir_reset_vec; /* XIR Reset vector */
/* 1e0 */ vaddr_t sigb_sir_reset_vec; /* SIR Reset Vector */
/* 1e8 */ vaddr_t sigb_red_state_reset_vec; /* RED State Reset Vector */
/* 1f0 */ uchar_t sigb_resv_array[SIGB_RESV]; /* reserved space */
} cpu_sgnblk_t; /* sizeof = 512 (0x200) = 128X */
#endif /* _ASM */
/*
* Mailbox commands.
*
* The commands are listed here so that they are in a central place
* for all users of the signature block mailbox. Want to be careful
* that some subsystems don't accidently use the same value for a
* command. For this reason we introduce a cookie for each subsystem.
*/
#define SIGB_HANDLER_BUSY (-2)
#define SIGB_BAD_MBOX_CMD (-1)
#define SSP_CMD ('S' << 8) /* generic SSP */
#define SSP_CMD_SUCCESS (SSP_CMD | 0x1)
#define SSP_GOTO_OBP (SSP_CMD | 0x2)
#define SSP_GOTO_PANIC (SSP_CMD | 0x3)
#define SSP_ENVIRON (SSP_CMD | 0x4) /* environmental intr */
#ifdef _KERNEL
#ifdef _STARFIRE
extern void juggle_sgnblk_poll(struct cpu *);
extern int sgnblk_poll_register(void (*)(processorid_t, cpu_sgnblk_t *));
extern int sgnblk_poll_unregister(void (*)(processorid_t, cpu_sgnblk_t *));
extern int sgnblk_poll_reference(void (*)(cpu_sgnblk_t *, void *), void *);
extern void sgnblk_poll_unreference(void (*)(cpu_sgnblk_t *, void *));
extern cpu_sgnblk_t *cpu_sgnblkp[NCPU];
/*
* Starfire specific signatures
*/
#define POST_SIG SIG_BLD('P', 'O')
#define DHLP_SIG SIG_BLD('D', 'H')
/*
* Starfire specific Sigblock states.
*/
#define SIGBST_NONE 0 /* no state */
#define SIGBST_RUN 1 /* running */
#define SIGBST_EXIT 2 /* finished */
#define SIGBST_PRERUN 3 /* pre-exec */
#define SIGBST_ARBSTOP 4 /* transient arbstop state */
#define SIGBST_RESET 5 /* reset */
#define SIGBST_POWEROFF 6 /* no power */
#define SIGBST_DETACHED 7 /* spinning in OBP after DR DETACH */
#define SIGBST_CALLBACK 8 /* kernel calling back into OBP */
#define SIGBST_WATCHDOG 9 /* OBP running after watchdog */
#define SIGBST_WATCHDOG_SYNC 10 /* OBP "sync" after watchdog reset */
#define SIGBST_OFFLINE 11 /* cpu offline */
#define SIGBST_BOOTING 12 /* booting */
#define SIGBST_UNKNOWN 13 /* unknown */
#define SIGBST_XIR 14 /* OBP running after XIR */
#define SIGBST_XIR_SYNC 15 /* OBP trying "sync" in XIR */
#define SIGBST_SIR 16 /* OBP running after SIR */
#define SIGBST_SIR_SYNC 17 /* OBP trying "sync" in SIR */
#define SIGBST_REDMODE 18 /* OBP running after REDMODE */
#define SIGBST_REDMODE_SYNC 19 /* OBP trying "sync" in REDMODE */
#define SIGBST_QUIESCED 20 /* system quiesced */
#define SIGBST_QUIESCE_INPROGRESS 21 /* system quiesce in-progress */
#define SIGBST_RESUME_INPROGRESS 22 /* system resume in-progress */
/*
* Starfire specific Sigblock sub-states
*/
#define EXIT_NULL 0
#define EXIT_HALT 1
#define EXIT_ENVIRON 2
#define EXIT_REBOOT 3
#define EXIT_PANIC1 4
#define EXIT_PANIC2 5
#define EXIT_HUNG 6
#define EXIT_WATCH 7
#define EXIT_PANIC_REBOOT 8
#define EXIT_WATCHDOG_REBOOT 9
#define EXIT_SOFT_INIT_RESET 10 /* SIR */
#define EXIT_EXTERN_INIT_RESET 11 /* XIR */
#define EXIT_REDMODE_REBOOT 12 /* REDMODE */
#define EXIT_OBP_RESET 13 /* OBP RESET */
#else
#define REGISTER_BBUS_INTR()
#define CPU_SGN_MAPIN(cpuid)
#define CPU_SGN_MAPOUT(cpuid)
#define CPU_SGN_EXISTS(cpuid) (0)
#define SGN_CPU_IS_OS(cpuid) (0)
#define SGN_CPU_IS_OBP(cpuid) (0)
#define SGN_CPU_STATE_IS_DETACHED(cpuid) (0)
#endif /* _STARFIRE */
#endif /* _KERNEL */
#ifdef __cplusplus
}
#endif
#endif /* _CPU_SGN_H */
|