xref: /illumos-gate/usr/src/uts/sun4u/opl/sys/mc-opl.h (revision 738dd194)
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 2006 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_opl_state {
95 	struct mc_opl_state *next;
96 	dev_info_t *mc_dip;
97 	uint32_t mc_status;
98 #define	MC_POLL_RUNNING	0x1
99 #define	MC_SOFT_SUSPENDED	0x2	/* suspended by DR */
100 #define	MC_DRIVER_SUSPENDED	0x4	/* DDI_SUSPEND */
101 #define	MC_MEMORYLESS		0x8
102 	uint32_t mc_board_num;		/* board# */
103 	uint64_t mc_start_address;	/* sb-mem-ranges */
104 	uint64_t mc_size;
105 	struct mc_bank {
106 		uint32_t  mcb_status;
107 #define	BANK_INSTALLED		0x80000000
108 #define	BANK_MIRROR_MODE	0x40000000	/* 0: normal  1: mirror */
109 #define	BANK_PTRL_RUNNING	0x00000001
110 		uint64_t  mcb_reg_base;
111 		uint32_t  mcb_ptrl_cntl;
112 	} mc_bank[BANKNUM_PER_SB];
113 	uchar_t		mc_trans_table[2][64];	/* csX-mac-pa-trans-table */
114 	kmutex_t	mc_lock;
115 	scf_log_t	*mc_scf_log[BANKNUM_PER_SB];
116 	scf_log_t	*mc_scf_log_tail[BANKNUM_PER_SB];
117 	int		mc_scf_total[BANKNUM_PER_SB];
118 	struct memlist	*mlist;
119 	int		mc_scf_retry[BANKNUM_PER_SB];
120 	int		mc_last_error;
121 			/* number of times memory scanned */
122 	uint64_t	mc_period[BANKNUM_PER_SB];
123 	uint32_t	mc_speed;
124 	int		mc_speedup_period[BANKNUM_PER_SB];
125 	int		mc_tick_left;
126 	mc_dimm_info_t	*mc_dimm_list;
127 } mc_opl_t;
128 
129 #define	IS_MIRROR(mcp, bn)	((mcp)->mc_bank[bn].mcb_status\
130 				& BANK_MIRROR_MODE)
131 typedef struct mc_addr {
132 	int ma_bd;		/* board number */
133 	int ma_bank;		/* bank number */
134 	uint32_t ma_dimm_addr;	/* DIMM address (same format as ERR_ADD) */
135 } mc_addr_t;
136 
137 typedef struct mc_rsaddr_info {		/* patrol restart address/info */
138 	struct mc_addr	mi_restartaddr;
139 	int		mi_valid;
140 	int		mi_injectrestart;
141 } mc_rsaddr_info_t;
142 
143 typedef struct mc_flt_stat {
144 	uint32_t  mf_type;		/* fault type */
145 #define	FLT_TYPE_INTERMITTENT_CE	0x0001
146 #define	FLT_TYPE_PERMANENT_CE		0x0002
147 #define	FLT_TYPE_UE			0x0003
148 #define	FLT_TYPE_SUE			0x0004
149 #define	FLT_TYPE_MUE			0x0005
150 #define	FLT_TYPE_CMPE			0x0006
151 	uint32_t  mf_cntl;		/* MAC_BANKm_PTRL_CNTL Register */
152 	uint32_t  mf_err_add;	/* MAC_BANKm_{PTRL|MI}_ERR_ADD Register */
153 	uint32_t  mf_err_log;	/* MAC_BANKm_{PTRL|MI}_ERR_LOG Register */
154 	uint32_t  mf_synd;
155 	uchar_t   mf_errlog_valid;
156 	uchar_t   mf_dimm_slot;
157 	uchar_t   mf_dram_place;
158 	uint64_t  mf_flt_paddr;		/* faulty physical address */
159 	mc_addr_t mf_flt_maddr;		/* faulty DIMM address */
160 } mc_flt_stat_t;
161 
162 typedef struct mc_aflt {
163 	uint64_t mflt_id;		/* gethrtime() at time of fault */
164 	mc_opl_t *mflt_mcp;		/* mc-opl structure */
165 	char *mflt_erpt_class;		/* ereport class name */
166 	int mflt_is_ptrl;		/* detected by PTRL or MI */
167 	int mflt_nflts;			/* 1 or 2 */
168 	int mflt_pr;			/* page retire flags */
169 	mc_flt_stat_t *mflt_stat[2];	/* fault status */
170 } mc_aflt_t;
171 
172 #define	MAC_PTRL_STAT(mcp, i)		(mcp->mc_bank[i].mcb_reg_base)
173 #define	MAC_PTRL_CNTL(mcp, i)		(mcp->mc_bank[i].mcb_reg_base + 0x10)
174 #define	MAC_PTRL_ERR_ADD(mcp, i)	(mcp->mc_bank[i].mcb_reg_base + 0x20)
175 #define	MAC_PTRL_ERR_LOG(mcp, i)	(mcp->mc_bank[i].mcb_reg_base + 0x24)
176 #define	MAC_MI_ERR_ADD(mcp, i)		(mcp->mc_bank[i].mcb_reg_base + 0x28)
177 #define	MAC_MI_ERR_LOG(mcp, i)		(mcp->mc_bank[i].mcb_reg_base + 0x2c)
178 #define	MAC_STATIC_ERR_ADD(mcp, i)	(mcp->mc_bank[i].mcb_reg_base + 0x30)
179 #define	MAC_STATIC_ERR_LOG(mcp, i)	(mcp->mc_bank[i].mcb_reg_base + 0x34)
180 #define	MAC_RESTART_ADD(mcp, i)		(mcp->mc_bank[i].mcb_reg_base + 0x40)
181 #define	MAC_REWRITE_ADD(mcp, i)		(mcp->mc_bank[i].mcb_reg_base + 0x44)
182 #define	MAC_EG_ADD(mcp, i)		(mcp->mc_bank[i].mcb_reg_base + 0x48)
183 #define	MAC_EG_CNTL(mcp, i)		(mcp->mc_bank[i].mcb_reg_base + 0x4c)
184 #define	MAC_MIRR(mcp, i)		(mcp->mc_bank[i].mcb_reg_base + 0x50)
185 
186 /* use PA[37:6] */
187 #define	MAC_RESTART_PA(pa)		((pa >> 6) & 0xffffffff)
188 /*
189  * MAC_BANKm_PTRL_STAT_Register
190  */
191 #define	MAC_STAT_PTRL_CE	0x00000020
192 #define	MAC_STAT_PTRL_UE	0x00000010
193 #define	MAC_STAT_PTRL_CMPE	0x00000008
194 #define	MAC_STAT_MI_CE		0x00000004
195 #define	MAC_STAT_MI_UE		0x00000002
196 #define	MAC_STAT_MI_CMPE	0x00000001
197 
198 #define	MAC_STAT_PTRL_ERRS	(MAC_STAT_PTRL_CE|MAC_STAT_PTRL_UE\
199 				|MAC_STAT_PTRL_CMPE)
200 #define	MAC_STAT_MI_ERRS	(MAC_STAT_MI_CE|MAC_STAT_MI_UE\
201 				|MAC_STAT_MI_CMPE)
202 
203 /*
204  * MAC_BANKm_PTRL_CTRL_Register
205  */
206 #define	MAC_CNTL_PTRL_START		0x80000000
207 #define	MAC_CNTL_USE_RESTART_ADD	0x40000000
208 #define	MAC_CNTL_PTRL_STOP		0x20000000
209 #define	MAC_CNTL_PTRL_INTERVAL		0x1c000000
210 #define	MAC_CNTL_PTRL_RESET		0x02000000
211 #define	MAC_CNTL_PTRL_STATUS		0x01000000
212 #define	MAC_CNTL_REW_REQ		0x00800000
213 #define	MAC_CNTL_REW_RESET		0x00400000
214 #define	MAC_CNTL_CS0_DEG_MODE		0x00200000
215 #define	MAC_CNTL_PTRL_CE		0x00008000
216 #define	MAC_CNTL_PTRL_UE		0x00004000
217 #define	MAC_CNTL_PTRL_CMPE		0x00002000
218 #define	MAC_CNTL_MI_CE			0x00001000
219 #define	MAC_CNTL_MI_UE			0x00000800
220 #define	MAC_CNTL_MI_CMPE		0x00000400
221 #define	MAC_CNTL_REW_CE			0x00000200
222 #define	MAC_CNTL_REW_UE			0x00000100
223 #define	MAC_CNTL_REW_END		0x00000080
224 #define	MAC_CNTL_PTRL_ADD_MAX		0x00000040
225 #define	MAC_CNTL_REW_CMPE		0x00000020
226 
227 #define	MAC_CNTL_PTRL_ERR_SHIFT		13
228 #define	MAC_CNTL_MI_ERR_SHIFT		10
229 
230 #define	MAC_CNTL_PTRL_PRESERVE_BITS	(MAC_CNTL_PTRL_INTERVAL)
231 
232 #define	MAC_CNTL_PTRL_ERRS	(MAC_CNTL_PTRL_CE|MAC_CNTL_PTRL_UE\
233 				|MAC_CNTL_PTRL_CMPE)
234 #define	MAC_CNTL_MI_ERRS	(MAC_CNTL_MI_CE|MAC_CNTL_MI_UE\
235 				|MAC_CNTL_MI_CMPE)
236 #define	MAC_CNTL_REW_ERRS	(MAC_CNTL_REW_CE|MAC_CNTL_REW_CMPE|\
237 				MAC_CNTL_REW_UE|MAC_CNTL_REW_END)
238 #define	MAC_CNTL_ALL_ERRS	(MAC_CNTL_PTRL_ERRS|\
239 				MAC_CNTL_MI_ERRS|MAC_CNTL_REW_ERRS)
240 
241 #define	MAC_ERRLOG_SYND_SHIFT		16
242 #define	MAC_ERRLOG_SYND_MASK		0xffff
243 #define	MAC_ERRLOG_DIMMSLOT_SHIFT	13
244 #define	MAC_ERRLOG_DIMMSLOT_MASK	0x7
245 #define	MAC_ERRLOG_DRAM_PLACE_SHIFT	8
246 #define	MAC_ERRLOG_DRAM_PLACE_MASK	0x1f
247 
248 #define	MAC_SET_ERRLOG_INFO(flt_stat)				\
249 	(flt_stat)->mf_errlog_valid = 1;			\
250 	(flt_stat)->mf_synd = ((flt_stat)->mf_err_log >>	\
251 		MAC_ERRLOG_SYND_SHIFT) &			\
252 		MAC_ERRLOG_SYND_MASK;				\
253 	(flt_stat)->mf_dimm_slot = ((flt_stat)->mf_err_log >>	\
254 		MAC_ERRLOG_DIMMSLOT_SHIFT) &			\
255 		MAC_ERRLOG_DIMMSLOT_MASK;			\
256 	(flt_stat)->mf_dram_place = ((flt_stat)->mf_err_log >>	\
257 		MAC_ERRLOG_DRAM_PLACE_SHIFT) &			\
258 		MAC_ERRLOG_DRAM_PLACE_MASK;
259 
260 extern void mc_write_cntl(mc_opl_t *, int, uint32_t);
261 #define	MAC_CMD(mcp, i, cmd)	mc_write_cntl(mcp, i, cmd)
262 
263 #define	MAC_PTRL_START(mcp, i)	{ if (!(ldphysio(MAC_PTRL_CNTL(mcp, i))	\
264 				& MAC_CNTL_PTRL_START))			\
265 				MAC_CMD((mcp), (i), MAC_CNTL_PTRL_START); }
266 
267 #define	MAC_PTRL_START_ADD(mcp, i)	MAC_CMD((mcp), (i),\
268 				MAC_CNTL_PTRL_START|MAC_CNTL_USE_RESTART_ADD)
269 #define	MAC_PTRL_STOP(mcp, i)	MAC_CMD((mcp), (i), MAC_CNTL_PTRL_STOP)
270 #define	MAC_PTRL_RESET(mcp, i)	MAC_CMD((mcp), (i), MAC_CNTL_PTRL_RESET)
271 #define	MAC_REW_REQ(mcp, i)	MAC_CMD((mcp), (i), MAC_CNTL_REW_REQ)
272 #define	MAC_REW_RESET(mcp, i)	MAC_CMD((mcp), (i), MAC_CNTL_REW_RESET)
273 #define	MAC_CLEAR_ERRS(mcp, i, errs)	MAC_CMD((mcp), (i), errs)
274 #define	MAC_CLEAR_ALL_ERRS(mcp, i)	MAC_CMD((mcp), (i),\
275 					MAC_CNTL_ALL_ERRS)
276 #define	MAC_CLEAR_MAX(mcp, i)	\
277 	MAC_CMD((mcp), (i), MAC_CNTL_PTRL_ADD_MAX)
278 
279 
280 /*
281  * MAC_BANKm_PTRL/MI_ERR_ADD/LOG_Register
282  */
283 #define	MAC_ERR_ADD_INVALID	0x80000000
284 #define	MAC_ERR_LOG_INVALID	0x00000080
285 
286 /*
287  * MAC_BANKm_STATIC_ERR_ADD_Register
288  */
289 #define	MAC_STATIC_ERR_VLD	0x80000000
290 
291 /*
292  * MAC_BANKm_MIRR_Register
293  */
294 #define	MAC_MIRR_MIRROR_MODE	0x80000000
295 #define	MAC_MIRR_BANK_EXCLUSIVE	0x40000000
296 
297 #define	OPL_BOARD_MAX	16
298 #define	OPL_BANK_MAX	8
299 
300 /*
301  * MAC_BANKm_EG_ADD_Register
302  */
303 #define	MAC_EG_ADD_MASK		0x7ffffffc
304 /*
305  * To set the EG_CNTL register, bit[26-25] and
306  * bit[21-20] must be cleared.  Then the other
307  * control bit should be set.  Then the bit[26-25]
308  * and bit[21-20] should be set while other bits
309  * should be the same as before.
310  */
311 #define	MAC_EG_CNTL_MASK	0x06300000
312 
313 #define	MAC_EG_ADD_FIX		0x80000000
314 #define	MAC_EG_FORCE_DERR00	0x40000000
315 #define	MAC_EG_FORCE_DERR16	0x20000000
316 #define	MAC_EG_FORCE_DERR64	0x10000000
317 #define	MAC_EG_FORCE_DERR80	0x08000000
318 #define	MAC_EG_DERR_ALWAYS	0x02000000
319 #define	MAC_EG_DERR_ONCE	0x04000000
320 #define	MAC_EG_DERR_NOP		0x06000000
321 #define	MAC_EG_FORCE_READ00	0x00800000
322 #define	MAC_EG_FORCE_READ16	0x00400000
323 #define	MAC_EG_RDERR_ALWAYS	0x00100000
324 #define	MAC_EG_RDERR_ONCE	0x00200000
325 #define	MAC_EG_RDERR_NOP	0x00300000
326 
327 #define	MAC_EG_SETUP_MASK	0xf9cfffff
328 
329 /* For MAC-PA translation */
330 #define	MC_ADDRESS_BITS	40
331 #define	PA_BITS_FOR_MAC	39
332 #define	INDEX_OF_BANK_SUPPLEMENT_BIT	39
333 #define	MP_NONE		128
334 #define	MP_BANK_0	129
335 #define	MP_BANK_1	130
336 #define	MP_BANK_2	131
337 
338 #define	CS_SHIFT	29
339 #define	MC_TT_ENTRIES	64
340 #define	MC_TT_CS	2
341 
342 
343 /* export interface for error injection */
344 extern int mc_inject_error(int error_type, uint64_t pa, uint32_t flags);
345 
346 #define	MC_INJECT_NOP			0x0
347 #define	MC_INJECT_INTERMITTENT_CE	0x1
348 #define	MC_INJECT_PERMANENT_CE		0x2
349 #define	MC_INJECT_UE			0x3
350 #define	MC_INJECT_INTERMITTENT_MCE	0x11
351 #define	MC_INJECT_PERMANENT_MCE		0x12
352 #define	MC_INJECT_SUE			0x13
353 #define	MC_INJECT_MUE			0x14
354 #define	MC_INJECT_CMPE			0x15
355 
356 #define	MC_INJECT_MIRROR_MODE		0x10
357 #define	MC_INJECT_MIRROR(x)		(x & MC_INJECT_MIRROR_MODE)
358 
359 #define	MC_INJECT_FLAG_PREFETCH	0x1
360 #define	MC_INJECT_FLAG_NO_TRAP	MC_INJECT_FLAG_PREFETCH
361 #define	MC_INJECT_FLAG_RESTART	0x2
362 #define	MC_INJECT_FLAG_POLL	0x4
363 #define	MC_INJECT_FLAG_RESET	0x8
364 #define	MC_INJECT_FLAG_OTHER	0x10
365 #define	MC_INJECT_FLAG_LD	0x20
366 #define	MC_INJECT_FLAG_ST	0x40
367 #define	MC_INJECT_FLAG_PATH	0x80
368 
369 #ifdef DEBUG
370 
371 #define	MCI_NOP		0x0
372 #define	MCI_CE		0x1
373 #define	MCI_PERM_CE	0x2
374 #define	MCI_UE		0x3
375 #define	MCI_SHOW_ALL	0x4
376 #define	MCI_SHOW_NONE	0x5
377 #define	MCI_CMP		0x6
378 #define	MCI_ALLOC	0x7
379 #define	MCI_M_CE	0x8
380 #define	MCI_M_PCE	0x9
381 #define	MCI_M_UE	0xA
382 #define	MCI_SUSPEND	0xB
383 #define	MCI_RESUME	0xC
384 
385 #endif
386 
387 #ifdef	__cplusplus
388 }
389 #endif
390 
391 #endif /* _SYS_MC_OPL_H */
392