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