mc-opl.h revision 2214:e2138a0f31fa
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
32extern "C" {
33#endif
34
35#include <sys/note.h>
36
37#ifdef	DEBUG
38#define	MC_LOG	if (oplmc_debug) printf
39extern 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 */
51extern uint32_t mc_ldphysio(uint64_t);
52extern 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
58typedef 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
68typedef	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
87typedef 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
94typedef 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)
131typedef 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
137typedef struct mc_addr_info {
138	struct mc_addr	mi_maddr;
139	int		mi_valid;
140	int		mi_advance;
141} mc_addr_info_t;
142
143typedef 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
162typedef 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
260extern 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	31
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 */
344extern 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_NO_TRAP	0x1
360#define	MC_INJECT_FLAG_RESTART	0x2
361#define	MC_INJECT_FLAG_POLL	0x4
362#define	MC_INJECT_FLAG_RESET	0x8
363#define	MC_INJECT_FLAG_OTHER	0x10
364#define	MC_INJECT_FLAG_LD	0x20
365#define	MC_INJECT_FLAG_ST	0x40
366#define	MC_INJECT_FLAG_PATH	0x80
367
368#ifdef DEBUG
369
370#define	MCI_NOP		0x0
371#define	MCI_CE		0x1
372#define	MCI_PERM_CE	0x2
373#define	MCI_UE		0x3
374#define	MCI_SHOW_ALL	0x4
375#define	MCI_SHOW_NONE	0x5
376#define	MCI_CMP		0x6
377#define	MCI_ALLOC	0x7
378#define	MCI_M_CE	0x8
379#define	MCI_M_PCE	0x9
380#define	MCI_M_UE	0xA
381#define	MCI_SUSPEND	0xB
382#define	MCI_RESUME	0xC
383
384#endif
385
386#ifdef	__cplusplus
387}
388#endif
389
390#endif /* _SYS_MC_OPL_H */
391