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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #ifndef _MEM_H 28 #define _MEM_H 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 #include <sys/types.h> 33 34 #ifdef __cplusplus 35 extern "C" { 36 #endif 37 38 /* 39 * FMRI plugin for the `mem' scheme. 40 * 41 * The mem scheme can be used to name individual memory modules, as well as 42 * groups of memory modules, also known as banks. The name `dimm' is used as a 43 * synonym for individual memory modules, for no good reason. Mem FMRIs can 44 * be further refined with the addition of a member which identifies a 45 * particular physical page within the bank or DIMM. The named page is as 46 * viewed by the VM system, and may thus span multiple memory modules. It will, 47 * however, be at least partially contained by the named bank or DIMM. 48 * 49 * Memory modules are identified by two things - their physical position, or 50 * slot, in the machine, and their serial number. DIMMs are identified by this 51 * tuple on platforms which support the retrieval of serial numbers. Platforms 52 * which don't have this support rely on the slot number, with the corresponding 53 * degradation in their ability to detect hardware changees. 54 * 55 * The physical location is embodied by the unum, which is highly specific to 56 * each platform, and bears a passing resemblance to the name of the slot, as 57 * printed on the actual hardware. The unum is mapped to a DIMM-specific 58 * device, which is then read to determine the serial number. See mem_disc.c 59 * for details of the process by which unums are mapped to devices, and 60 * mem_read.c for the code which actually retrieves the serial number from the 61 * device. 62 * 63 * Banks are also identified by unums, which must be broken apart into the 64 * unums which identify each constituent memory module. Serial numbers are 65 * retrieved for banks - one per member module - in the same way as for 66 * individual modules. See mem_unum.c for the code which bursts bank unums. 67 * 68 * Serial number retrieval, on platforms which support it, is very expensive 69 * (on the order of several tenths of a second, which adds up in a hurry on 70 * larger machines). So, while we pre-generate the list of DIMM device paths, 71 * we only read their serial numbers when requested by plugin consumers. To 72 * further reduce the perceived cost, we don't re-read until/unless we detect 73 * that a DR operation has taken place. 74 * 75 * Using the facilities described above, the plugin implements the following 76 * entry points: (see mem.c) 77 * 78 * - nvl2str: The printed representation of the named bank or DIMM is 79 * generated. No attempt is made to determine whether or not the named 80 * item is still present in the system. 81 * 82 * - expand: At the time of this writing, no platforms include bank or DIMM 83 * serial numbers in their ereports. As such, the serial number(s) must 84 * be added by the diagnosis engine. This entry point will read the 85 * serial number(s) for the named item, and will add it/them to the passed 86 * FMRI. Errors will be returned if the FMRI (unum) was unparseable, or if 87 * the serial number could not be retrieved. 88 * 89 * - present: Given a mem-schemed FMRI with a serial number, this entry 90 * point will attempt to determine whether the bank or module named in the 91 * FMRI is still present in the system at the same location. Programmer 92 * errors (invalid FMRIs) will be signalled to the caller. Warnings will 93 * be emitted for otherwise-valid FMRIs whose serial numbers could not be 94 * read, with the caller told that the FMRI is not present. 95 * 96 * - contains: Used to determine whether a given bank contains a given DIMM. 97 * No attempt is made to determine whether the module named by the FMRIs are 98 * actually present in the system. Programmer errors (invalidd FMRIs) will 99 * be returned to the caller. Warnings will be emitted for otherwise-valid 100 * FMRIs whose relationship could not be determined, with the caller told 101 * that there is no relationship. 102 */ 103 104 #define MEM_SERID_MAXLEN 9 /* 8+nul for SPD, 6+nul for SEEPROM */ 105 106 typedef struct mem_dimm_map { 107 struct mem_dimm_map *dm_next; /* The next DIMM map */ 108 char *dm_label; /* The UNUM for this DIMM */ 109 char *dm_device; /* Path to I2C device for DIMM */ 110 char dm_serid[MEM_SERID_MAXLEN]; /* Cached serial number */ 111 uint64_t dm_drgen; /* DR gen count for cached S/N */ 112 } mem_dimm_map_t; 113 114 typedef struct mem { 115 mem_dimm_map_t *mem_dm; /* List supported DIMMs */ 116 } mem_t; 117 118 extern int mem_discover(void); 119 extern void mem_destroy(void); 120 121 extern int mem_get_serid(const char *, char *, size_t); 122 123 extern int mem_unum_burst(const char *, char ***, size_t *); 124 extern int mem_unum_contains(const char *, const char *); 125 126 extern void mem_strarray_free(char **, size_t); 127 extern int mem_page_cmd(int, uint64_t); 128 129 extern mem_t mem; 130 131 #ifdef __cplusplus 132 } 133 #endif 134 135 #endif /* _MEM_H */ 136