xref: /illumos-gate/usr/src/uts/sun4u/opl/sys/mc-opl.h (revision 598f4ceed9327d2d6c2325dd67cae3aa06f7fea6)
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 (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #ifndef _SYS_MC_OPL_H
27 #define	_SYS_MC_OPL_H
28 
29 #pragma ident	"%Z%%M%	%I%	%E% SMI"
30 
31 #ifdef	__cplusplus
32 extern "C" {
33 #endif
34 
35 #include <sys/note.h>
36 
37 #ifdef	DEBUG
38 #define	MC_LOG	if (oplmc_debug) printf
39 extern int oplmc_debug;
40 #else
41 #define	MC_LOG		_NOTE(CONSTANTCONDITION) if (0) printf
42 #endif
43 
44 #define	MC_PATROL_INTERVAL_SEC	10
45 
46 #define	MC_POLL_EXIT	0x01
47 
48 /*
49  * load/store MAC register
50  */
51 extern uint32_t mc_ldphysio(uint64_t);
52 extern void mc_stphysio(uint64_t, uint32_t);
53 #define	LD_MAC_REG(paddr)	mc_ldphysio(paddr)
54 #define	ST_MAC_REG(paddr, data)	mc_stphysio((paddr), (data))
55 
56 #define	BANKNUM_PER_SB	8
57 
58 typedef struct {
59 	uint32_t cs_num;
60 	uint32_t cs_status;
61 	uint32_t cs_avail_hi;
62 	uint32_t cs_avail_low;
63 	uint32_t dimm_capa_hi;
64 	uint32_t dimm_capa_low;
65 	uint32_t ndimms;
66 } cs_status_t;
67 
68 typedef	struct scf_log {
69 	struct scf_log	*sl_next;
70 	int		sl_bank;
71 	uint32_t	sl_err_add;
72 	uint32_t	sl_err_log;
73 } scf_log_t;
74 
75 /*
76  * Current max serial number size is 12, but keep enough room
77  * to accomodate any future changes.
78  *
79  * Current max part number size is 18 + 18(Sun's partnumber + FJ's partnumber),
80  * but keep enough room to accomodate any future changes.
81  */
82 #define	MCOPL_MAX_DIMMNAME	3
83 #define	MCOPL_MAX_SERIAL	20
84 #define	MCOPL_MAX_PARTNUM	44
85 #define	MCOPL_MAX_SERIALID (MCOPL_MAX_SERIAL + MCOPL_MAX_PARTNUM)
86 
87 typedef struct mc_dimm_info {
88 	struct	mc_dimm_info *md_next;
89 	char	md_dimmname[MCOPL_MAX_DIMMNAME + 1];
90 	char	md_serial[MCOPL_MAX_SERIAL + 1];
91 	char	md_partnum[MCOPL_MAX_PARTNUM + 1];
92 } mc_dimm_info_t;
93 
94 typedef struct mc_retry_info {
95 	struct mc_retry_info *ri_next;
96 #define	RETRY_STATE_PENDING	0
97 #define	RETRY_STATE_ACTIVE	1
98 #define	RETRY_STATE_REWRITE	2
99 	int		   ri_state;
100 	uint32_t	   ri_addr;
101 } mc_retry_info_t;
102 
103 typedef struct mc_opl_state {
104 	struct mc_opl_state *next;
105 	dev_info_t *mc_dip;
106 	uint32_t mc_status;
107 #define	MC_POLL_RUNNING	0x1
108 #define	MC_SOFT_SUSPENDED	0x2	/* suspended by DR */
109 #define	MC_DRIVER_SUSPENDED	0x4	/* DDI_SUSPEND */
110 #define	MC_MEMORYLESS		0x8
111 	uint32_t mc_board_num;		/* board# */
112 	uint32_t mc_phys_board_num;	/* physical board# */
113 	uint64_t mc_start_address;	/* sb-mem-ranges */
114 	uint64_t mc_size;
115 	struct mc_bank {
116 		uint32_t  mcb_status;
117 #define	BANK_INSTALLED		0x80000000
118 #define	BANK_MIRROR_MODE	0x40000000	/* 0: normal  1: mirror */
119 #define	BANK_REWRITE_MODE	0x10000000
120 
121 #define	BANK_PTRL_RUNNING	0x00000001
122 
123 #define	MC_RETRY_COUNT	2
124 		mc_retry_info_t  mcb_retry_infos[MC_RETRY_COUNT];
125 		mc_retry_info_t	*mcb_retry_freelist;
126 		mc_retry_info_t	*mcb_retry_pending;
127 		mc_retry_info_t *mcb_active;
128 		int	  mcb_rewrite_count;
129 
130 		uint64_t  mcb_reg_base;
131 		uint32_t  mcb_ptrl_cntl;
132 	} mc_bank[BANKNUM_PER_SB];
133 	uchar_t		mc_trans_table[2][64];	/* csX-mac-pa-trans-table */
134 	kmutex_t	mc_lock;
135 	scf_log_t	*mc_scf_log[BANKNUM_PER_SB];
136 	scf_log_t	*mc_scf_log_tail[BANKNUM_PER_SB];
137 	int		mc_scf_total[BANKNUM_PER_SB];
138 	struct memlist	*mlist;
139 	int		mc_scf_retry[BANKNUM_PER_SB];
140 	int		mc_last_error;
141 			/* number of times memory scanned */
142 	uint64_t	mc_period[BANKNUM_PER_SB];
143 	uint32_t	mc_speed;
144 	int		mc_speedup_period[BANKNUM_PER_SB];
145 	int		mc_tick_left;
146 	mc_dimm_info_t	*mc_dimm_list;
147 } mc_opl_t;
148 
149 #define	IS_MIRROR(mcp, bn)	((mcp)->mc_bank[bn].mcb_status\
150 				& BANK_MIRROR_MODE)
151 typedef struct mc_addr {
152 	int ma_bd;		/* board number */
153 	int ma_phys_bd;	/* phyiscal board number */
154 	int ma_bank;		/* bank number */
155 	uint32_t ma_dimm_addr;	/* DIMM address (same format as ERR_ADD) */
156 } mc_addr_t;
157 
158 typedef struct mc_rsaddr_info {		/* patrol restart address/info */
159 	struct mc_addr	mi_restartaddr;
160 	int		mi_valid;
161 	int		mi_injectrestart;
162 } mc_rsaddr_info_t;
163 
164 typedef struct mc_flt_stat {
165 	uint32_t  mf_type;		/* fault type */
166 #define	FLT_TYPE_INTERMITTENT_CE	0x0001
167 #define	FLT_TYPE_PERMANENT_CE		0x0002
168 #define	FLT_TYPE_UE			0x0003
169 #define	FLT_TYPE_SUE			0x0004
170 #define	FLT_TYPE_MUE			0x0005
171 #define	FLT_TYPE_CMPE			0x0006
172 	uint32_t  mf_cntl;		/* MAC_BANKm_PTRL_CNTL Register */
173 	uint32_t  mf_err_add;	/* MAC_BANKm_{PTRL|MI}_ERR_ADD Register */
174 	uint32_t  mf_err_log;	/* MAC_BANKm_{PTRL|MI}_ERR_LOG Register */
175 	uint32_t  mf_synd;
176 	uchar_t   mf_errlog_valid;
177 	uchar_t   mf_dimm_slot;
178 	uchar_t   mf_dram_place;
179 	uint64_t  mf_flt_paddr;		/* faulty physical address */
180 	mc_addr_t mf_flt_maddr;		/* faulty DIMM address */
181 } mc_flt_stat_t;
182 
183 typedef struct mc_aflt {
184 	uint64_t mflt_id;		/* gethrtime() at time of fault */
185 	mc_opl_t *mflt_mcp;		/* mc-opl structure */
186 	char *mflt_erpt_class;		/* ereport class name */
187 	int mflt_is_ptrl;		/* detected by PTRL or MI */
188 	int mflt_nflts;			/* 1 or 2 */
189 	int mflt_pr;			/* page retire flags */
190 	mc_flt_stat_t *mflt_stat[2];	/* fault status */
191 } mc_aflt_t;
192 
193 typedef struct mc_flt_page {
194 	uint32_t err_add;		/* MAC_BANKm_{PTRL|MI}_ERR_ADD reg */
195 	uint32_t err_log;		/* MAC_BANKm_{PTRL|MI}_ERR_LOG reg */
196 	uint64_t fmri_addr;		/* FRU name string */
197 	uint32_t fmri_sz;		/* length of FRU name +1 */
198 } mc_flt_page_t;
199 
200 #define	MAC_PTRL_STAT(mcp, i)		(mcp->mc_bank[i].mcb_reg_base)
201 #define	MAC_PTRL_CNTL(mcp, i)		(mcp->mc_bank[i].mcb_reg_base + 0x10)
202 #define	MAC_PTRL_ERR_ADD(mcp, i)	(mcp->mc_bank[i].mcb_reg_base + 0x20)
203 #define	MAC_PTRL_ERR_LOG(mcp, i)	(mcp->mc_bank[i].mcb_reg_base + 0x24)
204 #define	MAC_MI_ERR_ADD(mcp, i)		(mcp->mc_bank[i].mcb_reg_base + 0x28)
205 #define	MAC_MI_ERR_LOG(mcp, i)		(mcp->mc_bank[i].mcb_reg_base + 0x2c)
206 #define	MAC_STATIC_ERR_ADD(mcp, i)	(mcp->mc_bank[i].mcb_reg_base + 0x30)
207 #define	MAC_STATIC_ERR_LOG(mcp, i)	(mcp->mc_bank[i].mcb_reg_base + 0x34)
208 #define	MAC_RESTART_ADD(mcp, i)		(mcp->mc_bank[i].mcb_reg_base + 0x40)
209 #define	MAC_REWRITE_ADD(mcp, i)		(mcp->mc_bank[i].mcb_reg_base + 0x44)
210 #define	MAC_EG_ADD(mcp, i)		(mcp->mc_bank[i].mcb_reg_base + 0x48)
211 #define	MAC_EG_CNTL(mcp, i)		(mcp->mc_bank[i].mcb_reg_base + 0x4c)
212 #define	MAC_MIRR(mcp, i)		(mcp->mc_bank[i].mcb_reg_base + 0x50)
213 
214 /* use PA[37:6] */
215 #define	MAC_RESTART_PA(pa)		((pa >> 6) & 0xffffffff)
216 
217 /*
218  * This is for changing MI_ERR_ADDR accuracy.
219  * Last two bits of PTRL_ERR_ADDR are always 0.
220  */
221 #define	ROUNDDOWN(a, n) (((a) & ~((n) - 1)))
222 #define	MC_BOUND_BYTE   4
223 
224 /*
225  * MAC_BANKm_PTRL_STAT_Register
226  */
227 #define	MAC_STAT_PTRL_CE	0x00000020
228 #define	MAC_STAT_PTRL_UE	0x00000010
229 #define	MAC_STAT_PTRL_CMPE	0x00000008
230 #define	MAC_STAT_MI_CE		0x00000004
231 #define	MAC_STAT_MI_UE		0x00000002
232 #define	MAC_STAT_MI_CMPE	0x00000001
233 
234 #define	MAC_STAT_PTRL_ERRS	(MAC_STAT_PTRL_CE|MAC_STAT_PTRL_UE\
235 				|MAC_STAT_PTRL_CMPE)
236 #define	MAC_STAT_MI_ERRS	(MAC_STAT_MI_CE|MAC_STAT_MI_UE\
237 				|MAC_STAT_MI_CMPE)
238 
239 /*
240  * MAC_BANKm_PTRL_CTRL_Register
241  */
242 #define	MAC_CNTL_PTRL_START		0x80000000
243 #define	MAC_CNTL_USE_RESTART_ADD	0x40000000
244 #define	MAC_CNTL_PTRL_STOP		0x20000000
245 #define	MAC_CNTL_PTRL_INTERVAL		0x1c000000
246 #define	MAC_CNTL_PTRL_RESET		0x02000000
247 #define	MAC_CNTL_PTRL_STATUS		0x01000000
248 #define	MAC_CNTL_REW_REQ		0x00800000
249 #define	MAC_CNTL_REW_RESET		0x00400000
250 #define	MAC_CNTL_CS0_DEG_MODE		0x00200000
251 #define	MAC_CNTL_PTRL_CE		0x00008000
252 #define	MAC_CNTL_PTRL_UE		0x00004000
253 #define	MAC_CNTL_PTRL_CMPE		0x00002000
254 #define	MAC_CNTL_MI_CE			0x00001000
255 #define	MAC_CNTL_MI_UE			0x00000800
256 #define	MAC_CNTL_MI_CMPE		0x00000400
257 #define	MAC_CNTL_REW_CE			0x00000200
258 #define	MAC_CNTL_REW_UE			0x00000100
259 #define	MAC_CNTL_REW_END		0x00000080
260 #define	MAC_CNTL_PTRL_ADD_MAX		0x00000040
261 #define	MAC_CNTL_REW_CMPE		0x00000020
262 
263 #define	MAC_CNTL_PTRL_ERR_SHIFT		13
264 #define	MAC_CNTL_MI_ERR_SHIFT		10
265 
266 #define	MAC_CNTL_PTRL_PRESERVE_BITS	(MAC_CNTL_PTRL_INTERVAL)
267 
268 #define	MAC_CNTL_PTRL_ERRS	(MAC_CNTL_PTRL_CE|MAC_CNTL_PTRL_UE\
269 				|MAC_CNTL_PTRL_CMPE)
270 #define	MAC_CNTL_MI_ERRS	(MAC_CNTL_MI_CE|MAC_CNTL_MI_UE\
271 				|MAC_CNTL_MI_CMPE)
272 #define	MAC_CNTL_REW_ERRS	(MAC_CNTL_REW_CE|MAC_CNTL_REW_CMPE|\
273 				MAC_CNTL_REW_UE|MAC_CNTL_REW_END)
274 #define	MAC_CNTL_ALL_ERRS	(MAC_CNTL_PTRL_ERRS|\
275 				MAC_CNTL_MI_ERRS|MAC_CNTL_REW_ERRS)
276 
277 #define	MAC_ERRLOG_SYND_SHIFT		16
278 #define	MAC_ERRLOG_SYND_MASK		0xffff
279 #define	MAC_ERRLOG_DIMMSLOT_SHIFT	13
280 #define	MAC_ERRLOG_DIMMSLOT_MASK	0x7
281 #define	MAC_ERRLOG_DRAM_PLACE_SHIFT	8
282 #define	MAC_ERRLOG_DRAM_PLACE_MASK	0x1f
283 
284 #define	MAC_SET_ERRLOG_INFO(flt_stat)				\
285 	(flt_stat)->mf_errlog_valid = 1;			\
286 	(flt_stat)->mf_synd = ((flt_stat)->mf_err_log >>	\
287 		MAC_ERRLOG_SYND_SHIFT) &			\
288 		MAC_ERRLOG_SYND_MASK;				\
289 	(flt_stat)->mf_dimm_slot = ((flt_stat)->mf_err_log >>	\
290 		MAC_ERRLOG_DIMMSLOT_SHIFT) &			\
291 		MAC_ERRLOG_DIMMSLOT_MASK;			\
292 	(flt_stat)->mf_dram_place = ((flt_stat)->mf_err_log >>	\
293 		MAC_ERRLOG_DRAM_PLACE_SHIFT) &			\
294 		MAC_ERRLOG_DRAM_PLACE_MASK;
295 
296 extern void mc_write_cntl(mc_opl_t *, int, uint32_t);
297 #define	MAC_CMD(mcp, i, cmd)	mc_write_cntl(mcp, i, cmd)
298 
299 #define	MAC_PTRL_START(mcp, i)	{ if (!(ldphysio(MAC_PTRL_CNTL(mcp, i))	\
300 				& MAC_CNTL_PTRL_START))			\
301 				MAC_CMD((mcp), (i), MAC_CNTL_PTRL_START); }
302 
303 #define	MAC_PTRL_START_ADD(mcp, i)	MAC_CMD((mcp), (i),\
304 				MAC_CNTL_PTRL_START|MAC_CNTL_USE_RESTART_ADD)
305 #define	MAC_PTRL_STOP(mcp, i)	MAC_CMD((mcp), (i), MAC_CNTL_PTRL_STOP)
306 #define	MAC_PTRL_RESET(mcp, i)	MAC_CMD((mcp), (i), MAC_CNTL_PTRL_RESET)
307 #define	MAC_REW_REQ(mcp, i)	MAC_CMD((mcp), (i), MAC_CNTL_REW_REQ)
308 #define	MAC_REW_RESET(mcp, i)	MAC_CMD((mcp), (i), MAC_CNTL_REW_RESET)
309 #define	MAC_CLEAR_ERRS(mcp, i, errs)	MAC_CMD((mcp), (i), errs)
310 #define	MAC_CLEAR_ALL_ERRS(mcp, i)	MAC_CMD((mcp), (i),\
311 					MAC_CNTL_ALL_ERRS)
312 #define	MAC_CLEAR_MAX(mcp, i)	\
313 	MAC_CMD((mcp), (i), MAC_CNTL_PTRL_ADD_MAX)
314 
315 
316 /*
317  * MAC_BANKm_PTRL/MI_ERR_ADD/LOG_Register
318  */
319 #define	MAC_ERR_ADD_INVALID	0x80000000
320 #define	MAC_ERR_LOG_INVALID	0x00000080
321 
322 /*
323  * MAC_BANKm_STATIC_ERR_ADD_Register
324  */
325 #define	MAC_STATIC_ERR_VLD	0x80000000
326 
327 /*
328  * MAC_BANKm_MIRR_Register
329  */
330 #define	MAC_MIRR_MIRROR_MODE	0x80000000
331 #define	MAC_MIRR_BANK_EXCLUSIVE	0x40000000
332 
333 #define	OPL_BOARD_MAX	16
334 #define	OPL_BANK_MAX	8
335 
336 #define	MC_SET_REWRITE_MODE(mcp, bank)				\
337 	((mcp)->mc_bank[bank].mcb_status |= BANK_REWRITE_MODE)
338 
339 #define	MC_CLEAR_REWRITE_MODE(mcp, bank)				\
340 	((mcp)->mc_bank[bank].mcb_status &= ~BANK_REWRITE_MODE)
341 
342 #define	MC_REWRITE_MODE(mcp, bank)				\
343 	((mcp)->mc_bank[bank].mcb_status & BANK_REWRITE_MODE)
344 
345 #define	MC_REWRITE_ACTIVE(mcp, bank)					\
346 	((mcp)->mc_bank[bank].mcb_active)
347 
348 /*
349  * MAC_BANKm_EG_ADD_Register
350  */
351 #define	MAC_EG_ADD_MASK		0x7ffffffc
352 /*
353  * To set the EG_CNTL register, bit[26-25] and
354  * bit[21-20] must be cleared.  Then the other
355  * control bit should be set.  Then the bit[26-25]
356  * and bit[21-20] should be set while other bits
357  * should be the same as before.
358  */
359 #define	MAC_EG_CNTL_MASK	0x06300000
360 
361 #define	MAC_EG_ADD_FIX		0x80000000
362 #define	MAC_EG_FORCE_DERR00	0x40000000
363 #define	MAC_EG_FORCE_DERR16	0x20000000
364 #define	MAC_EG_FORCE_DERR64	0x10000000
365 #define	MAC_EG_FORCE_DERR80	0x08000000
366 #define	MAC_EG_DERR_ALWAYS	0x02000000
367 #define	MAC_EG_DERR_ONCE	0x04000000
368 #define	MAC_EG_DERR_NOP		0x06000000
369 #define	MAC_EG_FORCE_READ00	0x00800000
370 #define	MAC_EG_FORCE_READ16	0x00400000
371 #define	MAC_EG_RDERR_ALWAYS	0x00100000
372 #define	MAC_EG_RDERR_ONCE	0x00200000
373 #define	MAC_EG_RDERR_NOP	0x00300000
374 
375 #define	MAC_EG_SETUP_MASK	0xf9cfffff
376 
377 /* For MAC-PA translation */
378 #define	MC_ADDRESS_BITS	40
379 #define	PA_BITS_FOR_MAC	39
380 #define	INDEX_OF_BANK_SUPPLEMENT_BIT	39
381 #define	MP_NONE		128
382 #define	MP_BANK_0	129
383 #define	MP_BANK_1	130
384 #define	MP_BANK_2	131
385 
386 #define	CS_SHIFT	29
387 #define	MC_TT_ENTRIES	64
388 #define	MC_TT_CS	2
389 
390 
391 /* export interface for error injection */
392 extern int mc_inject_error(int error_type, uint64_t pa, uint32_t flags);
393 
394 #define	MC_INJECT_NOP			0x0
395 #define	MC_INJECT_INTERMITTENT_CE	0x1
396 #define	MC_INJECT_PERMANENT_CE		0x2
397 #define	MC_INJECT_UE			0x3
398 #define	MC_INJECT_INTERMITTENT_MCE	0x11
399 #define	MC_INJECT_PERMANENT_MCE		0x12
400 #define	MC_INJECT_SUE			0x13
401 #define	MC_INJECT_MUE			0x14
402 #define	MC_INJECT_CMPE			0x15
403 
404 #define	MC_INJECT_MIRROR_MODE		0x10
405 #define	MC_INJECT_MIRROR(x)		(x & MC_INJECT_MIRROR_MODE)
406 
407 #define	MC_INJECT_FLAG_PREFETCH	0x1
408 #define	MC_INJECT_FLAG_NO_TRAP	MC_INJECT_FLAG_PREFETCH
409 #define	MC_INJECT_FLAG_RESTART	0x2
410 #define	MC_INJECT_FLAG_POLL	0x4
411 #define	MC_INJECT_FLAG_RESET	0x8
412 #define	MC_INJECT_FLAG_OTHER	0x10
413 #define	MC_INJECT_FLAG_LD	0x20
414 #define	MC_INJECT_FLAG_ST	0x40
415 #define	MC_INJECT_FLAG_PATH	0x80
416 
417 #define	MCIOC			('M' << 8)
418 #define	MCIOC_FAULT_PAGE	(MCIOC|1)
419 
420 #ifdef DEBUG
421 
422 #define	MCI_NOP		0x0
423 #define	MCI_CE		0x1
424 #define	MCI_PERM_CE	0x2
425 #define	MCI_UE		0x3
426 #define	MCI_SHOW_ALL	0x4
427 #define	MCI_SHOW_NONE	0x5
428 #define	MCI_CMP		0x6
429 #define	MCI_ALLOC	0x7
430 #define	MCI_M_CE	0x8
431 #define	MCI_M_PCE	0x9
432 #define	MCI_M_UE	0xA
433 #define	MCI_SUSPEND	0xB
434 #define	MCI_RESUME	0xC
435 
436 #endif
437 
438 #ifdef	__cplusplus
439 }
440 #endif
441 
442 #endif /* _SYS_MC_OPL_H */
443