xref: /titanic_50/usr/src/uts/sun4u/opl/sys/mc-opl.h (revision 582271e8d649568c83e9a016cc0d54265389c5d9)
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 2007 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 #define	MAC_PTRL_STAT(mcp, i)		(mcp->mc_bank[i].mcb_reg_base)
194 #define	MAC_PTRL_CNTL(mcp, i)		(mcp->mc_bank[i].mcb_reg_base + 0x10)
195 #define	MAC_PTRL_ERR_ADD(mcp, i)	(mcp->mc_bank[i].mcb_reg_base + 0x20)
196 #define	MAC_PTRL_ERR_LOG(mcp, i)	(mcp->mc_bank[i].mcb_reg_base + 0x24)
197 #define	MAC_MI_ERR_ADD(mcp, i)		(mcp->mc_bank[i].mcb_reg_base + 0x28)
198 #define	MAC_MI_ERR_LOG(mcp, i)		(mcp->mc_bank[i].mcb_reg_base + 0x2c)
199 #define	MAC_STATIC_ERR_ADD(mcp, i)	(mcp->mc_bank[i].mcb_reg_base + 0x30)
200 #define	MAC_STATIC_ERR_LOG(mcp, i)	(mcp->mc_bank[i].mcb_reg_base + 0x34)
201 #define	MAC_RESTART_ADD(mcp, i)		(mcp->mc_bank[i].mcb_reg_base + 0x40)
202 #define	MAC_REWRITE_ADD(mcp, i)		(mcp->mc_bank[i].mcb_reg_base + 0x44)
203 #define	MAC_EG_ADD(mcp, i)		(mcp->mc_bank[i].mcb_reg_base + 0x48)
204 #define	MAC_EG_CNTL(mcp, i)		(mcp->mc_bank[i].mcb_reg_base + 0x4c)
205 #define	MAC_MIRR(mcp, i)		(mcp->mc_bank[i].mcb_reg_base + 0x50)
206 
207 /* use PA[37:6] */
208 #define	MAC_RESTART_PA(pa)		((pa >> 6) & 0xffffffff)
209 /*
210  * MAC_BANKm_PTRL_STAT_Register
211  */
212 #define	MAC_STAT_PTRL_CE	0x00000020
213 #define	MAC_STAT_PTRL_UE	0x00000010
214 #define	MAC_STAT_PTRL_CMPE	0x00000008
215 #define	MAC_STAT_MI_CE		0x00000004
216 #define	MAC_STAT_MI_UE		0x00000002
217 #define	MAC_STAT_MI_CMPE	0x00000001
218 
219 #define	MAC_STAT_PTRL_ERRS	(MAC_STAT_PTRL_CE|MAC_STAT_PTRL_UE\
220 				|MAC_STAT_PTRL_CMPE)
221 #define	MAC_STAT_MI_ERRS	(MAC_STAT_MI_CE|MAC_STAT_MI_UE\
222 				|MAC_STAT_MI_CMPE)
223 
224 /*
225  * MAC_BANKm_PTRL_CTRL_Register
226  */
227 #define	MAC_CNTL_PTRL_START		0x80000000
228 #define	MAC_CNTL_USE_RESTART_ADD	0x40000000
229 #define	MAC_CNTL_PTRL_STOP		0x20000000
230 #define	MAC_CNTL_PTRL_INTERVAL		0x1c000000
231 #define	MAC_CNTL_PTRL_RESET		0x02000000
232 #define	MAC_CNTL_PTRL_STATUS		0x01000000
233 #define	MAC_CNTL_REW_REQ		0x00800000
234 #define	MAC_CNTL_REW_RESET		0x00400000
235 #define	MAC_CNTL_CS0_DEG_MODE		0x00200000
236 #define	MAC_CNTL_PTRL_CE		0x00008000
237 #define	MAC_CNTL_PTRL_UE		0x00004000
238 #define	MAC_CNTL_PTRL_CMPE		0x00002000
239 #define	MAC_CNTL_MI_CE			0x00001000
240 #define	MAC_CNTL_MI_UE			0x00000800
241 #define	MAC_CNTL_MI_CMPE		0x00000400
242 #define	MAC_CNTL_REW_CE			0x00000200
243 #define	MAC_CNTL_REW_UE			0x00000100
244 #define	MAC_CNTL_REW_END		0x00000080
245 #define	MAC_CNTL_PTRL_ADD_MAX		0x00000040
246 #define	MAC_CNTL_REW_CMPE		0x00000020
247 
248 #define	MAC_CNTL_PTRL_ERR_SHIFT		13
249 #define	MAC_CNTL_MI_ERR_SHIFT		10
250 
251 #define	MAC_CNTL_PTRL_PRESERVE_BITS	(MAC_CNTL_PTRL_INTERVAL)
252 
253 #define	MAC_CNTL_PTRL_ERRS	(MAC_CNTL_PTRL_CE|MAC_CNTL_PTRL_UE\
254 				|MAC_CNTL_PTRL_CMPE)
255 #define	MAC_CNTL_MI_ERRS	(MAC_CNTL_MI_CE|MAC_CNTL_MI_UE\
256 				|MAC_CNTL_MI_CMPE)
257 #define	MAC_CNTL_REW_ERRS	(MAC_CNTL_REW_CE|MAC_CNTL_REW_CMPE|\
258 				MAC_CNTL_REW_UE|MAC_CNTL_REW_END)
259 #define	MAC_CNTL_ALL_ERRS	(MAC_CNTL_PTRL_ERRS|\
260 				MAC_CNTL_MI_ERRS|MAC_CNTL_REW_ERRS)
261 
262 #define	MAC_ERRLOG_SYND_SHIFT		16
263 #define	MAC_ERRLOG_SYND_MASK		0xffff
264 #define	MAC_ERRLOG_DIMMSLOT_SHIFT	13
265 #define	MAC_ERRLOG_DIMMSLOT_MASK	0x7
266 #define	MAC_ERRLOG_DRAM_PLACE_SHIFT	8
267 #define	MAC_ERRLOG_DRAM_PLACE_MASK	0x1f
268 
269 #define	MAC_SET_ERRLOG_INFO(flt_stat)				\
270 	(flt_stat)->mf_errlog_valid = 1;			\
271 	(flt_stat)->mf_synd = ((flt_stat)->mf_err_log >>	\
272 		MAC_ERRLOG_SYND_SHIFT) &			\
273 		MAC_ERRLOG_SYND_MASK;				\
274 	(flt_stat)->mf_dimm_slot = ((flt_stat)->mf_err_log >>	\
275 		MAC_ERRLOG_DIMMSLOT_SHIFT) &			\
276 		MAC_ERRLOG_DIMMSLOT_MASK;			\
277 	(flt_stat)->mf_dram_place = ((flt_stat)->mf_err_log >>	\
278 		MAC_ERRLOG_DRAM_PLACE_SHIFT) &			\
279 		MAC_ERRLOG_DRAM_PLACE_MASK;
280 
281 extern void mc_write_cntl(mc_opl_t *, int, uint32_t);
282 #define	MAC_CMD(mcp, i, cmd)	mc_write_cntl(mcp, i, cmd)
283 
284 #define	MAC_PTRL_START(mcp, i)	{ if (!(ldphysio(MAC_PTRL_CNTL(mcp, i))	\
285 				& MAC_CNTL_PTRL_START))			\
286 				MAC_CMD((mcp), (i), MAC_CNTL_PTRL_START); }
287 
288 #define	MAC_PTRL_START_ADD(mcp, i)	MAC_CMD((mcp), (i),\
289 				MAC_CNTL_PTRL_START|MAC_CNTL_USE_RESTART_ADD)
290 #define	MAC_PTRL_STOP(mcp, i)	MAC_CMD((mcp), (i), MAC_CNTL_PTRL_STOP)
291 #define	MAC_PTRL_RESET(mcp, i)	MAC_CMD((mcp), (i), MAC_CNTL_PTRL_RESET)
292 #define	MAC_REW_REQ(mcp, i)	MAC_CMD((mcp), (i), MAC_CNTL_REW_REQ)
293 #define	MAC_REW_RESET(mcp, i)	MAC_CMD((mcp), (i), MAC_CNTL_REW_RESET)
294 #define	MAC_CLEAR_ERRS(mcp, i, errs)	MAC_CMD((mcp), (i), errs)
295 #define	MAC_CLEAR_ALL_ERRS(mcp, i)	MAC_CMD((mcp), (i),\
296 					MAC_CNTL_ALL_ERRS)
297 #define	MAC_CLEAR_MAX(mcp, i)	\
298 	MAC_CMD((mcp), (i), MAC_CNTL_PTRL_ADD_MAX)
299 
300 
301 /*
302  * MAC_BANKm_PTRL/MI_ERR_ADD/LOG_Register
303  */
304 #define	MAC_ERR_ADD_INVALID	0x80000000
305 #define	MAC_ERR_LOG_INVALID	0x00000080
306 
307 /*
308  * MAC_BANKm_STATIC_ERR_ADD_Register
309  */
310 #define	MAC_STATIC_ERR_VLD	0x80000000
311 
312 /*
313  * MAC_BANKm_MIRR_Register
314  */
315 #define	MAC_MIRR_MIRROR_MODE	0x80000000
316 #define	MAC_MIRR_BANK_EXCLUSIVE	0x40000000
317 
318 #define	OPL_BOARD_MAX	16
319 #define	OPL_BANK_MAX	8
320 
321 #define	MC_SET_REWRITE_MODE(mcp, bank)				\
322 	((mcp)->mc_bank[bank].mcb_status |= BANK_REWRITE_MODE)
323 
324 #define	MC_CLEAR_REWRITE_MODE(mcp, bank)				\
325 	((mcp)->mc_bank[bank].mcb_status &= ~BANK_REWRITE_MODE)
326 
327 #define	MC_REWRITE_MODE(mcp, bank)				\
328 	((mcp)->mc_bank[bank].mcb_status & BANK_REWRITE_MODE)
329 
330 #define	MC_REWRITE_ACTIVE(mcp, bank)					\
331 	((mcp)->mc_bank[bank].mcb_active)
332 
333 /*
334  * MAC_BANKm_EG_ADD_Register
335  */
336 #define	MAC_EG_ADD_MASK		0x7ffffffc
337 /*
338  * To set the EG_CNTL register, bit[26-25] and
339  * bit[21-20] must be cleared.  Then the other
340  * control bit should be set.  Then the bit[26-25]
341  * and bit[21-20] should be set while other bits
342  * should be the same as before.
343  */
344 #define	MAC_EG_CNTL_MASK	0x06300000
345 
346 #define	MAC_EG_ADD_FIX		0x80000000
347 #define	MAC_EG_FORCE_DERR00	0x40000000
348 #define	MAC_EG_FORCE_DERR16	0x20000000
349 #define	MAC_EG_FORCE_DERR64	0x10000000
350 #define	MAC_EG_FORCE_DERR80	0x08000000
351 #define	MAC_EG_DERR_ALWAYS	0x02000000
352 #define	MAC_EG_DERR_ONCE	0x04000000
353 #define	MAC_EG_DERR_NOP		0x06000000
354 #define	MAC_EG_FORCE_READ00	0x00800000
355 #define	MAC_EG_FORCE_READ16	0x00400000
356 #define	MAC_EG_RDERR_ALWAYS	0x00100000
357 #define	MAC_EG_RDERR_ONCE	0x00200000
358 #define	MAC_EG_RDERR_NOP	0x00300000
359 
360 #define	MAC_EG_SETUP_MASK	0xf9cfffff
361 
362 /* For MAC-PA translation */
363 #define	MC_ADDRESS_BITS	40
364 #define	PA_BITS_FOR_MAC	39
365 #define	INDEX_OF_BANK_SUPPLEMENT_BIT	39
366 #define	MP_NONE		128
367 #define	MP_BANK_0	129
368 #define	MP_BANK_1	130
369 #define	MP_BANK_2	131
370 
371 #define	CS_SHIFT	29
372 #define	MC_TT_ENTRIES	64
373 #define	MC_TT_CS	2
374 
375 
376 /* export interface for error injection */
377 extern int mc_inject_error(int error_type, uint64_t pa, uint32_t flags);
378 
379 #define	MC_INJECT_NOP			0x0
380 #define	MC_INJECT_INTERMITTENT_CE	0x1
381 #define	MC_INJECT_PERMANENT_CE		0x2
382 #define	MC_INJECT_UE			0x3
383 #define	MC_INJECT_INTERMITTENT_MCE	0x11
384 #define	MC_INJECT_PERMANENT_MCE		0x12
385 #define	MC_INJECT_SUE			0x13
386 #define	MC_INJECT_MUE			0x14
387 #define	MC_INJECT_CMPE			0x15
388 
389 #define	MC_INJECT_MIRROR_MODE		0x10
390 #define	MC_INJECT_MIRROR(x)		(x & MC_INJECT_MIRROR_MODE)
391 
392 #define	MC_INJECT_FLAG_PREFETCH	0x1
393 #define	MC_INJECT_FLAG_NO_TRAP	MC_INJECT_FLAG_PREFETCH
394 #define	MC_INJECT_FLAG_RESTART	0x2
395 #define	MC_INJECT_FLAG_POLL	0x4
396 #define	MC_INJECT_FLAG_RESET	0x8
397 #define	MC_INJECT_FLAG_OTHER	0x10
398 #define	MC_INJECT_FLAG_LD	0x20
399 #define	MC_INJECT_FLAG_ST	0x40
400 #define	MC_INJECT_FLAG_PATH	0x80
401 
402 #ifdef DEBUG
403 
404 #define	MCI_NOP		0x0
405 #define	MCI_CE		0x1
406 #define	MCI_PERM_CE	0x2
407 #define	MCI_UE		0x3
408 #define	MCI_SHOW_ALL	0x4
409 #define	MCI_SHOW_NONE	0x5
410 #define	MCI_CMP		0x6
411 #define	MCI_ALLOC	0x7
412 #define	MCI_M_CE	0x8
413 #define	MCI_M_PCE	0x9
414 #define	MCI_M_UE	0xA
415 #define	MCI_SUSPEND	0xB
416 #define	MCI_RESUME	0xC
417 
418 #endif
419 
420 #ifdef	__cplusplus
421 }
422 #endif
423 
424 #endif /* _SYS_MC_OPL_H */
425