summaryrefslogtreecommitdiff
path: root/usr/src/cmd/fm/schemes/mem/mem.h
blob: 34a6c1bb105cd57de9fbf5f5cf4dee86d8c7b2e5 (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
/*
 * 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 2008 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef _MEM_H
#define	_MEM_H

#include <sys/types.h>
#include <sys/nvpair.h>

#ifdef __cplusplus
extern "C" {
#endif

/*
 * FMRI plugin for the `mem' scheme.
 *
 * The mem scheme can be used to name individual memory modules, as well as
 * groups of memory modules, also known as banks.  The name `dimm' is used as a
 * synonym for individual memory modules, for no good reason.  Mem FMRIs can
 * be further refined with the addition of a member which identifies a
 * particular physical page within the bank or DIMM.  The named page is as
 * viewed by the VM system, and may thus span multiple memory modules.  It will,
 * however, be at least partially contained by the named bank or DIMM.
 *
 * Memory modules are identified by two things - their physical position, or
 * slot, in the machine, and their serial number.  DIMMs are identified by this
 * tuple on platforms which support the retrieval of serial numbers.  Platforms
 * which don't have this support rely on the slot number, with the corresponding
 * degradation in their ability to detect hardware changees.
 *
 * The physical location is embodied by the unum, which is highly specific to
 * each platform, and bears a passing resemblance to the name of the slot, as
 * printed on the actual hardware.  The unum is mapped to a DIMM-specific
 * device, which is then read to determine the serial number.  See mem_disc.c
 * for details of the process by which unums are mapped to devices, and
 * mem_read.c for the code which actually retrieves the serial number from the
 * device.
 *
 * Banks are also identified by unums, which must be broken apart into the
 * unums which identify each constituent memory module.  Serial numbers are
 * retrieved for banks - one per member module - in the same way as for
 * individual modules.  See mem_unum.c for the code which bursts bank unums.
 *
 * Serial number retrieval, on platforms which support it, is very expensive
 * (on the order of several tenths of a second, which adds up in a hurry on
 * larger machines).  So, while we pre-generate the list of DIMM device paths,
 * we only read their serial numbers when requested by plugin consumers.  To
 * further reduce the perceived cost, we don't re-read until/unless we detect
 * that a DR operation has taken place.
 *
 * Using the facilities described above, the plugin implements the following
 * entry points: (see mem.c)
 *
 *   - nvl2str: The printed representation of the named bank or DIMM is
 *     generated.  No attempt is made to determine whether or not the named
 *     item is still present in the system.
 *
 *   - expand: For platforms which do not include bank or DIMM
 *     serial numbers in their ereports, this entry point will read the
 *     serial number(s) for the named item, and will add it/them to the passed
 *     FMRI.  Errors will be returned if the FMRI (unum) was unparseable, or if
 *     the serial number could not be retrieved.
 *
 *   - present: Given a mem-schemed FMRI with a serial number, this entry
 *     point will attempt to determine whether the bank or module named in the
 *     FMRI is still present in the system at the same location.  Programmer
 *     errors (invalid FMRIs) will be signalled to the caller.  Warnings will
 *     be emitted for otherwise-valid FMRIs whose serial numbers could not be
 *     read, with the caller told that the FMRI is not present.
 *
 *   - contains: Used to determine whether a given bank contains a given DIMM.
 *     No attempt is made to determine whether the module named by the FMRIs are
 *     actually present in the system.  Programmer errors (invalidd FMRIs) will
 *     be returned to the caller.  Warnings will be emitted for otherwise-valid
 *     FMRIs whose relationship could not be determined, with the caller told
 *     that there is no relationship.
 */

/*
 * 18+nul for SPD, 6+nul for SEEPROM, 15+nul max for Serengeti, Starcat, LW8.
 * 18 for Sun Partnumber, 18 partner partnumber, 12 serialnumber for OPL.
 */
#define	MEM_SERID_MAXLEN	64
#define	MAX_DIMMS_PER_BANK	4

typedef struct mem_dimm_map {
	struct mem_dimm_map *dm_next;	/* The next DIMM map */
	char *dm_label;			/* The UNUM for this DIMM */
	char *dm_device;		/* Path to I2C device for DIMM */
	char dm_serid[MEM_SERID_MAXLEN]; /* Cached serial number */
	char *dm_part;			/* DIMM part number */
	uint64_t dm_drgen;		/* DR gen count for cached S/N */
} mem_dimm_map_t;

typedef struct mem_bank_map {
	struct mem_bank_map *bm_next;	/* the next bank map overall */
	struct mem_bank_map *bm_grp;	/* next bank map in group */
	uint64_t	bm_mask;
	uint64_t	bm_match;
	uint16_t	bm_shift;	/* dimms-per-reference shift */
	mem_dimm_map_t *bm_dimm[MAX_DIMMS_PER_BANK];
} mem_bank_map_t;

typedef struct mem_grp {
	struct mem_grp *mg_next;
	size_t		mg_size;
	mem_bank_map_t *mg_bank;
} mem_grp_t;

typedef struct mem_seg_map {
	struct mem_seg_map *sm_next;	/* the next segment map */
	uint64_t	sm_base;	/* base address for this segment */
	uint64_t	sm_size;	/* size for this segment */
	mem_grp_t	*sm_grp;
} mem_seg_map_t;


typedef struct mem {
	mem_dimm_map_t *mem_dm;		/* List supported DIMMs */
	uint64_t mem_memconfig;		/* HV memory-configuration-id# */
	mem_seg_map_t *mem_seg;		/* list of defined segments */
	mem_bank_map_t *mem_bank;
	mem_grp_t *mem_group;		/* groups of banks for a segment */
} mem_t;

extern int mem_discover(void);
extern int mem_get_serid(const char *, char *, size_t);
extern int mem_get_serids_by_unum(const char *, char ***, size_t *);
extern void mem_expand_opt(nvlist_t *, char *, char **);

extern int mem_unum_burst(const char *, char ***, size_t *);
extern int mem_unum_contains(const char *, const char *);
extern int mem_unum_rewrite(nvlist_t *, nvlist_t **);

extern void mem_strarray_free(char **, size_t);

extern mem_t mem;

#ifdef __cplusplus
}
#endif

#endif /* _MEM_H */