summaryrefslogtreecommitdiff
path: root/usr/src/uts/intel/io/mc-amd/mcamd.h
blob: ec9fcb5077da58488e97342bdfab3d299a9844fa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */

/*
 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef _MCAMD_H
#define	_MCAMD_H

/*
 * Header file for the mc-amd AMD memory-controller driver.  This should be
 * included from that driver source alone - any more-widely useful definitions
 * belong in mc_amd.h.
 */

#include <sys/types.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>
#include <sys/ksynch.h>
#include <sys/mc_amd.h>
#include <sys/cpu_module.h>
#include <mcamd_api.h>
#include <mcamd_err.h>
#include <mcamd_dimmcfg.h>

#ifdef __cplusplus
extern "C" {
#endif

#if	MC_CHIP_DIMMPERCS > MC_UNUM_NDIMM
#error	"MC_CHIP_DIMMPERCS exceeds MC_UNUM_NDIMM"
#endif

/*
 * The memory controller configuration registers are accessed via PCI bus 0,
 * device 0x18 + nodeid, functions 0 to 3.  The function numbers are
 * MC_FUNC_*, defined in mc_amd.h.
 *
 * We do not attach to function 3 "Miscellaneous Control" pci1022,1103
 * since the agpgart driver already attaches to that function; instead we
 * retrieve what function 3 parameters we require via direct PCI Mechanism 1
 * accesses
 *
 * The memory controller driver attaches to these device nodes, but publishes
 * a single minor node.  We need to ensure that the minor node can be
 * consistently mapped back to a single (and the same) device node, so we
 * need to pick one to be used.  We'll use the dram address map device node,
 * as it'll be the last to be attached.
 */
#define	MC_FUNC_DEVIMAP		MC_FUNC_DRAMCTL
#define	MC_FUNC_NUM		(MC_FUNC_MISCCTL + 1)

#define	MC_FUNC_HTCONFIG_BINDNM	"pci1022,1100"
#define	MC_FUNC_ADDRMAP_BINDNM	"pci1022,1101"
#define	MC_FUNC_DRAMCTL_BINDNM	"pci1022,1102"

typedef struct mc_func {
	uint_t mcf_instance;
	dev_info_t *mcf_devi;
} mc_func_t;

typedef struct mc_dimm mc_dimm_t;
typedef struct mc_cs mc_cs_t;
typedef struct mc mc_t;

/*
 * Node types for mch_type below.  These are used in array indexing.
 */
#define	MC_NT_MC		0
#define	MC_NT_CS		1
#define	MC_NT_DIMM		2
#define	MC_NT_NTYPES		3

typedef struct mc_hdr {
	uint_t mch_type;
	union {
		mc_t *_mch_mc;
		mc_cs_t *_mch_cs;
	} _mch_ptr;
} mc_hdr_t;

#define	mch_mc		_mch_ptr._mch_mc

struct mc_dimm {
	mc_hdr_t mcd_hdr;			/* id, pointer to parent */
	mc_dimm_t *mcd_next;			/* next dimm for this MC */
	mc_cs_t *mcd_cs[MC_CHIP_DIMMRANKMAX];	/* associated chip-selects */
	const mcdcfg_csl_t *mcd_csl[MC_CHIP_DIMMRANKMAX]; /* cs lines */
	mcamd_prop_t mcd_num;			/* dimm number */
	mcamd_prop_t mcd_size;			/* dimm size in bytes */
};

#define	mcd_mc mcd_hdr.mch_mc

/*
 * Chip-select properties.  If a chip-select is associated with just one
 * dimm (whether it be on the A or B dram channel) that number will be
 * in csp_dimmnums[0];  if the chip-select is associated with two dimms
 * then csp_dimmnums[0] has the dimm from channel A and csp_dimmnums[1] has
 * the partner dimm from channel B.
 */
typedef struct mccs_props {
	mcamd_prop_t csp_num;			/* Chip-select number */
	mcamd_prop_t csp_base;			/* DRAM CS Base */
	mcamd_prop_t csp_mask;			/* DRAM CS Mask */
	mcamd_prop_t csp_size;			/* Chip-select bank size */
	mcamd_prop_t csp_csbe;			/* Chip-select bank enable */
	mcamd_prop_t csp_spare;			/* Spare */
	mcamd_prop_t csp_testfail;		/* TestFail */
	mcamd_prop_t csp_dimmnums[MC_CHIP_DIMMPERCS]; /* dimm(s) in cs */
	mcamd_prop_t csp_dimmrank;		/* rank # on dimms */
} mccs_props_t;

/*
 * Chip-select config register values
 */
typedef struct mccs_cfgrefs {
	mcamd_cfgreg_t csr_csbase;		/* Raw CS base reg */
	mcamd_cfgreg_t csr_csmask;		/* Raw CS mask reg */
} mccs_cfgregs_t;

struct mc_cs {
	mc_hdr_t mccs_hdr;			/* id, pointer to parent */
	mc_cs_t *mccs_next;			/* Next chip-select of MC */
	mc_dimm_t *mccs_dimm[MC_CHIP_DIMMPERCS]; /* dimms for this cs */
	const mcdcfg_csl_t *mccs_csl[MC_CHIP_DIMMPERCS]; /* cs lines */
	mccs_props_t mccs_props;		/* Properties */
	mccs_cfgregs_t mccs_cfgregs;		/* Raw config values */
};

#define	mccs_mc	mccs_hdr.mch_mc

/*
 * Memory controller properties.
 */
typedef struct mc_props {
	mcamd_prop_t mcp_num;		/* Associated *chip* number */
	mcamd_prop_t mcp_rev;		/* Chip revision (MC_REV_*) */
	mcamd_prop_t mcp_base;		/* base address for mc's drams */
	mcamd_prop_t mcp_lim;		/* limit address for mc's drams */
	mcamd_prop_t mcp_ilen;		/* interleave enable */
	mcamd_prop_t mcp_ilsel;		/* interleave select */
	mcamd_prop_t mcp_csintlvfctr;	/* cs bank interleave factor */
	mcamd_prop_t mcp_dramhole_size;	/* DRAM Hole Size */
	mcamd_prop_t mcp_accwidth;	/* dram access width (64 or 128) */
	mcamd_prop_t mcp_csbankmapreg;	/* chip-select bank mapping reg */
	mcamd_prop_t mcp_bnkswzl;	/* BankSwizzle enabled */
	mcamd_prop_t mcp_mod64mux;	/* Mismtached DIMMs support enabled */
	mcamd_prop_t mcp_sparecs;	/* cs# replaced by online spare */
	mcamd_prop_t mcp_badcs;		/* cs# replaced by online spare */
} mc_props_t;

/*
 * Memory controller config register values
 */
typedef struct mc_cfgregs {
	mcamd_cfgreg_t mcr_htroute[MC_CHIP_MAXNODES];
	mcamd_cfgreg_t mcr_htnodeid;
	mcamd_cfgreg_t mcr_htunitid;
	mcamd_cfgreg_t mcr_drambase;
	mcamd_cfgreg_t mcr_dramlimit;
	mcamd_cfgreg_t mcr_dramhole;
	mcamd_cfgreg_t mcr_dramcfglo;
	mcamd_cfgreg_t mcr_dramcfghi;
	mcamd_cfgreg_t mcr_drammisc;
	mcamd_cfgreg_t mcr_nbcfg;
	mcamd_cfgreg_t mcr_sparectl;
	mcamd_cfgreg_t mcr_scrubctl;
	mcamd_cfgreg_t mcr_scrubaddrlo;
	mcamd_cfgreg_t mcr_scrubaddrhi;
} mc_cfgregs_t;

struct mc {
	mc_hdr_t mc_hdr;			/* id */
	struct mc *mc_next;			/* next MC instance */
	const char *mc_revname;			/* revision name string */
	uint32_t mc_socket;			/* Package type */
	uint_t mc_ref;				/* reference (attach) count */
	mc_func_t mc_funcs[MC_FUNC_NUM];	/* Instance, devinfo, ... */
	mc_cs_t *mc_cslist;			/* All active chip-selects */
	mc_cs_t *mc_cslast;			/* End of chip-select list */
	mc_dimm_t *mc_dimmlist;			/* List of all logical DIMMs, */
	mc_dimm_t *mc_dimmlast;			/* linked via mcd_mcnext */
	mc_props_t mc_props;			/* Properties */
	mc_cfgregs_t mc_cfgregs;		/* Raw config values */
	hrtime_t mc_spareswaptime;		/* If initiated by us */
	nvlist_t *mc_nvl;			/* nvlist for export */
	char *mc_snapshot;			/* packed nvlist for libmc */
	size_t mc_snapshotsz;			/* packed nvlist buffer size */
	uint_t mc_snapshotgen;			/* snapshot generation number */
	int mc_csdiscontig;			/* chip-selects discontiguous */
	uint_t smb_chipid;			/* smbios chip instance */
	nvlist_t *smb_bboard;			/* smbios chip's parent */
};

typedef struct mcamd_hdl {
	int mcamd_errno;
	int mcamd_debug;
} mcamd_hdl_t;

extern mc_t *mc_list;
extern krwlock_t mc_lock;

extern void mcamd_mkhdl(mcamd_hdl_t *);
extern void mcamd_mc_register(cmi_hdl_t, mc_t *);
extern void mcamd_ereport_post(mc_t *, const char *, mc_unum_t *, uint64_t);

/*
 * mcamd_mc_ops prototypes
 */
extern cmi_errno_t mcamd_patounum_wrap(void *, uint64_t, uint8_t, uint8_t,
    uint32_t, int, mc_unum_t *);
extern cmi_errno_t mcamd_unumtopa_wrap(void *, mc_unum_t *, nvlist_t *,
    uint64_t *);

/*
 * Internal functions
 */
cmi_errno_t mcamd_cmierr(int, mcamd_hdl_t *);

#ifdef __cplusplus
}
#endif

#endif /* _MCAMD_H */