10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 51883Stsien * Common Development and Distribution License (the "License"). 61883Stsien * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 211414Scindi 220Sstevel@tonic-gate /* 23*6434Stsien * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 240Sstevel@tonic-gate * Use is subject to license terms. 250Sstevel@tonic-gate */ 260Sstevel@tonic-gate 270Sstevel@tonic-gate #ifndef _MEM_H 280Sstevel@tonic-gate #define _MEM_H 290Sstevel@tonic-gate 300Sstevel@tonic-gate #include <sys/types.h> 311186Sayznaga #include <sys/nvpair.h> 320Sstevel@tonic-gate 330Sstevel@tonic-gate #ifdef __cplusplus 340Sstevel@tonic-gate extern "C" { 350Sstevel@tonic-gate #endif 360Sstevel@tonic-gate 370Sstevel@tonic-gate /* 380Sstevel@tonic-gate * FMRI plugin for the `mem' scheme. 390Sstevel@tonic-gate * 400Sstevel@tonic-gate * The mem scheme can be used to name individual memory modules, as well as 410Sstevel@tonic-gate * groups of memory modules, also known as banks. The name `dimm' is used as a 420Sstevel@tonic-gate * synonym for individual memory modules, for no good reason. Mem FMRIs can 430Sstevel@tonic-gate * be further refined with the addition of a member which identifies a 440Sstevel@tonic-gate * particular physical page within the bank or DIMM. The named page is as 450Sstevel@tonic-gate * viewed by the VM system, and may thus span multiple memory modules. It will, 460Sstevel@tonic-gate * however, be at least partially contained by the named bank or DIMM. 470Sstevel@tonic-gate * 480Sstevel@tonic-gate * Memory modules are identified by two things - their physical position, or 490Sstevel@tonic-gate * slot, in the machine, and their serial number. DIMMs are identified by this 500Sstevel@tonic-gate * tuple on platforms which support the retrieval of serial numbers. Platforms 510Sstevel@tonic-gate * which don't have this support rely on the slot number, with the corresponding 520Sstevel@tonic-gate * degradation in their ability to detect hardware changees. 530Sstevel@tonic-gate * 540Sstevel@tonic-gate * The physical location is embodied by the unum, which is highly specific to 550Sstevel@tonic-gate * each platform, and bears a passing resemblance to the name of the slot, as 560Sstevel@tonic-gate * printed on the actual hardware. The unum is mapped to a DIMM-specific 570Sstevel@tonic-gate * device, which is then read to determine the serial number. See mem_disc.c 580Sstevel@tonic-gate * for details of the process by which unums are mapped to devices, and 590Sstevel@tonic-gate * mem_read.c for the code which actually retrieves the serial number from the 600Sstevel@tonic-gate * device. 610Sstevel@tonic-gate * 620Sstevel@tonic-gate * Banks are also identified by unums, which must be broken apart into the 630Sstevel@tonic-gate * unums which identify each constituent memory module. Serial numbers are 640Sstevel@tonic-gate * retrieved for banks - one per member module - in the same way as for 650Sstevel@tonic-gate * individual modules. See mem_unum.c for the code which bursts bank unums. 660Sstevel@tonic-gate * 670Sstevel@tonic-gate * Serial number retrieval, on platforms which support it, is very expensive 680Sstevel@tonic-gate * (on the order of several tenths of a second, which adds up in a hurry on 690Sstevel@tonic-gate * larger machines). So, while we pre-generate the list of DIMM device paths, 700Sstevel@tonic-gate * we only read their serial numbers when requested by plugin consumers. To 710Sstevel@tonic-gate * further reduce the perceived cost, we don't re-read until/unless we detect 720Sstevel@tonic-gate * that a DR operation has taken place. 730Sstevel@tonic-gate * 740Sstevel@tonic-gate * Using the facilities described above, the plugin implements the following 750Sstevel@tonic-gate * entry points: (see mem.c) 760Sstevel@tonic-gate * 770Sstevel@tonic-gate * - nvl2str: The printed representation of the named bank or DIMM is 780Sstevel@tonic-gate * generated. No attempt is made to determine whether or not the named 790Sstevel@tonic-gate * item is still present in the system. 800Sstevel@tonic-gate * 814759Ssd77468 * - expand: For platforms which do not include bank or DIMM 824759Ssd77468 * serial numbers in their ereports, this entry point will read the 830Sstevel@tonic-gate * serial number(s) for the named item, and will add it/them to the passed 840Sstevel@tonic-gate * FMRI. Errors will be returned if the FMRI (unum) was unparseable, or if 850Sstevel@tonic-gate * the serial number could not be retrieved. 860Sstevel@tonic-gate * 870Sstevel@tonic-gate * - present: Given a mem-schemed FMRI with a serial number, this entry 880Sstevel@tonic-gate * point will attempt to determine whether the bank or module named in the 890Sstevel@tonic-gate * FMRI is still present in the system at the same location. Programmer 900Sstevel@tonic-gate * errors (invalid FMRIs) will be signalled to the caller. Warnings will 910Sstevel@tonic-gate * be emitted for otherwise-valid FMRIs whose serial numbers could not be 920Sstevel@tonic-gate * read, with the caller told that the FMRI is not present. 930Sstevel@tonic-gate * 940Sstevel@tonic-gate * - contains: Used to determine whether a given bank contains a given DIMM. 950Sstevel@tonic-gate * No attempt is made to determine whether the module named by the FMRIs are 960Sstevel@tonic-gate * actually present in the system. Programmer errors (invalidd FMRIs) will 970Sstevel@tonic-gate * be returned to the caller. Warnings will be emitted for otherwise-valid 980Sstevel@tonic-gate * FMRIs whose relationship could not be determined, with the caller told 990Sstevel@tonic-gate * that there is no relationship. 1000Sstevel@tonic-gate */ 1010Sstevel@tonic-gate 1022214Sav145390 /* 1032214Sav145390 * 18+nul for SPD, 6+nul for SEEPROM, 15+nul max for Serengeti, Starcat, LW8. 1042214Sav145390 * 18 for Sun Partnumber, 18 partner partnumber, 12 serialnumber for OPL. 1052214Sav145390 */ 1062214Sav145390 #define MEM_SERID_MAXLEN 64 107*6434Stsien #define MAX_DIMMS_PER_BANK 4 1084759Ssd77468 1090Sstevel@tonic-gate typedef struct mem_dimm_map { 1100Sstevel@tonic-gate struct mem_dimm_map *dm_next; /* The next DIMM map */ 1110Sstevel@tonic-gate char *dm_label; /* The UNUM for this DIMM */ 1120Sstevel@tonic-gate char *dm_device; /* Path to I2C device for DIMM */ 1130Sstevel@tonic-gate char dm_serid[MEM_SERID_MAXLEN]; /* Cached serial number */ 1143325Ssd77468 char *dm_part; /* DIMM part number */ 1150Sstevel@tonic-gate uint64_t dm_drgen; /* DR gen count for cached S/N */ 1160Sstevel@tonic-gate } mem_dimm_map_t; 1170Sstevel@tonic-gate 118*6434Stsien typedef struct mem_bank_map { 119*6434Stsien struct mem_bank_map *bm_next; /* the next bank map overall */ 120*6434Stsien struct mem_bank_map *bm_grp; /* next bank map in group */ 121*6434Stsien uint64_t bm_mask; 122*6434Stsien uint64_t bm_match; 123*6434Stsien uint16_t bm_shift; /* dimms-per-reference shift */ 124*6434Stsien mem_dimm_map_t *bm_dimm[MAX_DIMMS_PER_BANK]; 125*6434Stsien } mem_bank_map_t; 126*6434Stsien 127*6434Stsien typedef struct mem_grp { 128*6434Stsien struct mem_grp *mg_next; 129*6434Stsien size_t mg_size; 130*6434Stsien mem_bank_map_t *mg_bank; 131*6434Stsien } mem_grp_t; 132*6434Stsien 133*6434Stsien typedef struct mem_seg_map { 134*6434Stsien struct mem_seg_map *sm_next; /* the next segment map */ 135*6434Stsien uint64_t sm_base; /* base address for this segment */ 136*6434Stsien uint64_t sm_size; /* size for this segment */ 137*6434Stsien mem_grp_t *sm_grp; 138*6434Stsien } mem_seg_map_t; 139*6434Stsien 140*6434Stsien 1410Sstevel@tonic-gate typedef struct mem { 1420Sstevel@tonic-gate mem_dimm_map_t *mem_dm; /* List supported DIMMs */ 143600Stsien uint64_t mem_memconfig; /* HV memory-configuration-id# */ 1444759Ssd77468 mem_seg_map_t *mem_seg; /* list of defined segments */ 145*6434Stsien mem_bank_map_t *mem_bank; 146*6434Stsien mem_grp_t *mem_group; /* groups of banks for a segment */ 1470Sstevel@tonic-gate } mem_t; 1480Sstevel@tonic-gate 1490Sstevel@tonic-gate extern int mem_discover(void); 1500Sstevel@tonic-gate extern int mem_get_serid(const char *, char *, size_t); 1514759Ssd77468 extern int mem_get_serids_by_unum(const char *, char ***, size_t *); 1524759Ssd77468 extern void mem_expand_opt(nvlist_t *, char *, char **); 1530Sstevel@tonic-gate 1540Sstevel@tonic-gate extern int mem_unum_burst(const char *, char ***, size_t *); 1550Sstevel@tonic-gate extern int mem_unum_contains(const char *, const char *); 1561414Scindi extern int mem_unum_rewrite(nvlist_t *, nvlist_t **); 1570Sstevel@tonic-gate 1580Sstevel@tonic-gate extern void mem_strarray_free(char **, size_t); 1590Sstevel@tonic-gate 1600Sstevel@tonic-gate extern mem_t mem; 1610Sstevel@tonic-gate 1620Sstevel@tonic-gate #ifdef __cplusplus 1630Sstevel@tonic-gate } 1640Sstevel@tonic-gate #endif 1650Sstevel@tonic-gate 1660Sstevel@tonic-gate #endif /* _MEM_H */ 167