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