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 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #ifndef _MCAMD_H 28 #define _MCAMD_H 29 30 /* 31 * Header file for the mc-amd AMD memory-controller driver. This should be 32 * included from that driver source alone - any more-widely useful definitions 33 * belong in mc_amd.h. 34 */ 35 36 #include <sys/types.h> 37 #include <sys/ddi.h> 38 #include <sys/sunddi.h> 39 #include <sys/ksynch.h> 40 #include <sys/mc_amd.h> 41 #include <sys/cpu_module.h> 42 #include <mcamd_api.h> 43 #include <mcamd_err.h> 44 #include <mcamd_dimmcfg.h> 45 46 #ifdef __cplusplus 47 extern "C" { 48 #endif 49 50 #if MC_CHIP_DIMMPERCS > MC_UNUM_NDIMM 51 #error "MC_CHIP_DIMMPERCS exceeds MC_UNUM_NDIMM" 52 #endif 53 54 /* 55 * The memory controller configuration registers are accessed via PCI bus 0, 56 * device 0x18 + nodeid, functions 0 to 3. The function numbers are 57 * MC_FUNC_*, defined in mc_amd.h. 58 * 59 * We do not attach to function 3 "Miscellaneous Control" pci1022,1103 60 * since the agpgart driver already attaches to that function; instead we 61 * retrieve what function 3 parameters we require via direct PCI Mechanism 1 62 * accesses 63 * 64 * The memory controller driver attaches to these device nodes, but publishes 65 * a single minor node. We need to ensure that the minor node can be 66 * consistently mapped back to a single (and the same) device node, so we 67 * need to pick one to be used. We'll use the dram address map device node, 68 * as it'll be the last to be attached. 69 */ 70 #define MC_FUNC_DEVIMAP MC_FUNC_DRAMCTL 71 #define MC_FUNC_NUM (MC_FUNC_MISCCTL + 1) 72 73 #define MC_FUNC_HTCONFIG_BINDNM "pci1022,1100" 74 #define MC_FUNC_ADDRMAP_BINDNM "pci1022,1101" 75 #define MC_FUNC_DRAMCTL_BINDNM "pci1022,1102" 76 77 typedef struct mc_func { 78 uint_t mcf_instance; 79 dev_info_t *mcf_devi; 80 } mc_func_t; 81 82 typedef struct mc_dimm mc_dimm_t; 83 typedef struct mc_cs mc_cs_t; 84 typedef struct mc mc_t; 85 86 /* 87 * Node types for mch_type below. These are used in array indexing. 88 */ 89 #define MC_NT_MC 0 90 #define MC_NT_CS 1 91 #define MC_NT_DIMM 2 92 #define MC_NT_NTYPES 3 93 94 typedef struct mc_hdr { 95 uint_t mch_type; 96 union { 97 mc_t *_mch_mc; 98 mc_cs_t *_mch_cs; 99 } _mch_ptr; 100 } mc_hdr_t; 101 102 #define mch_mc _mch_ptr._mch_mc 103 104 struct mc_dimm { 105 mc_hdr_t mcd_hdr; /* id, pointer to parent */ 106 mc_dimm_t *mcd_next; /* next dimm for this MC */ 107 mc_cs_t *mcd_cs[MC_CHIP_DIMMRANKMAX]; /* associated chip-selects */ 108 const mcdcfg_csl_t *mcd_csl[MC_CHIP_DIMMRANKMAX]; /* cs lines */ 109 mcamd_prop_t mcd_num; /* dimm number */ 110 mcamd_prop_t mcd_size; /* dimm size in bytes */ 111 }; 112 113 #define mcd_mc mcd_hdr.mch_mc 114 115 /* 116 * Chip-select properties. If a chip-select is associated with just one 117 * dimm (whether it be on the A or B dram channel) that number will be 118 * in csp_dimmnums[0]; if the chip-select is associated with two dimms 119 * then csp_dimmnums[0] has the dimm from channel A and csp_dimmnums[1] has 120 * the partner dimm from channel B. 121 */ 122 typedef struct mccs_props { 123 mcamd_prop_t csp_num; /* Chip-select number */ 124 mcamd_prop_t csp_base; /* DRAM CS Base */ 125 mcamd_prop_t csp_mask; /* DRAM CS Mask */ 126 mcamd_prop_t csp_size; /* Chip-select bank size */ 127 mcamd_prop_t csp_csbe; /* Chip-select bank enable */ 128 mcamd_prop_t csp_spare; /* Spare */ 129 mcamd_prop_t csp_testfail; /* TestFail */ 130 mcamd_prop_t csp_dimmnums[MC_CHIP_DIMMPERCS]; /* dimm(s) in cs */ 131 mcamd_prop_t csp_dimmrank; /* rank # on dimms */ 132 } mccs_props_t; 133 134 /* 135 * Chip-select config register values 136 */ 137 typedef struct mccs_cfgrefs { 138 mcamd_cfgreg_t csr_csbase; /* Raw CS base reg */ 139 mcamd_cfgreg_t csr_csmask; /* Raw CS mask reg */ 140 } mccs_cfgregs_t; 141 142 struct mc_cs { 143 mc_hdr_t mccs_hdr; /* id, pointer to parent */ 144 mc_cs_t *mccs_next; /* Next chip-select of MC */ 145 mc_dimm_t *mccs_dimm[MC_CHIP_DIMMPERCS]; /* dimms for this cs */ 146 const mcdcfg_csl_t *mccs_csl[MC_CHIP_DIMMPERCS]; /* cs lines */ 147 mccs_props_t mccs_props; /* Properties */ 148 mccs_cfgregs_t mccs_cfgregs; /* Raw config values */ 149 }; 150 151 #define mccs_mc mccs_hdr.mch_mc 152 153 /* 154 * Memory controller properties. 155 */ 156 typedef struct mc_props { 157 mcamd_prop_t mcp_num; /* Associated *chip* number */ 158 mcamd_prop_t mcp_rev; /* Chip revision (MC_REV_*) */ 159 mcamd_prop_t mcp_base; /* base address for mc's drams */ 160 mcamd_prop_t mcp_lim; /* limit address for mc's drams */ 161 mcamd_prop_t mcp_ilen; /* interleave enable */ 162 mcamd_prop_t mcp_ilsel; /* interleave select */ 163 mcamd_prop_t mcp_csintlvfctr; /* cs bank interleave factor */ 164 mcamd_prop_t mcp_dramhole_size; /* DRAM Hole Size */ 165 mcamd_prop_t mcp_accwidth; /* dram access width (64 or 128) */ 166 mcamd_prop_t mcp_csbankmapreg; /* chip-select bank mapping reg */ 167 mcamd_prop_t mcp_bnkswzl; /* BankSwizzle enabled */ 168 mcamd_prop_t mcp_mod64mux; /* Mismtached DIMMs support enabled */ 169 mcamd_prop_t mcp_sparecs; /* cs# replaced by online spare */ 170 mcamd_prop_t mcp_badcs; /* cs# replaced by online spare */ 171 } mc_props_t; 172 173 /* 174 * Memory controller config register values 175 */ 176 typedef struct mc_cfgregs { 177 mcamd_cfgreg_t mcr_htroute[MC_CHIP_MAXNODES]; 178 mcamd_cfgreg_t mcr_htnodeid; 179 mcamd_cfgreg_t mcr_htunitid; 180 mcamd_cfgreg_t mcr_drambase; 181 mcamd_cfgreg_t mcr_dramlimit; 182 mcamd_cfgreg_t mcr_dramhole; 183 mcamd_cfgreg_t mcr_dramcfglo; 184 mcamd_cfgreg_t mcr_dramcfghi; 185 mcamd_cfgreg_t mcr_drammisc; 186 mcamd_cfgreg_t mcr_nbcfg; 187 mcamd_cfgreg_t mcr_sparectl; 188 mcamd_cfgreg_t mcr_scrubctl; 189 mcamd_cfgreg_t mcr_scrubaddrlo; 190 mcamd_cfgreg_t mcr_scrubaddrhi; 191 } mc_cfgregs_t; 192 193 struct mc { 194 mc_hdr_t mc_hdr; /* id */ 195 struct mc *mc_next; /* next MC instance */ 196 const char *mc_revname; /* revision name string */ 197 uint32_t mc_socket; /* Package type */ 198 uint_t mc_ref; /* reference (attach) count */ 199 mc_func_t mc_funcs[MC_FUNC_NUM]; /* Instance, devinfo, ... */ 200 mc_cs_t *mc_cslist; /* All active chip-selects */ 201 mc_cs_t *mc_cslast; /* End of chip-select list */ 202 mc_dimm_t *mc_dimmlist; /* List of all logical DIMMs, */ 203 mc_dimm_t *mc_dimmlast; /* linked via mcd_mcnext */ 204 mc_props_t mc_props; /* Properties */ 205 mc_cfgregs_t mc_cfgregs; /* Raw config values */ 206 hrtime_t mc_spareswaptime; /* If initiated by us */ 207 nvlist_t *mc_nvl; /* nvlist for export */ 208 char *mc_snapshot; /* packed nvlist for libmc */ 209 size_t mc_snapshotsz; /* packed nvlist buffer size */ 210 uint_t mc_snapshotgen; /* snapshot generation number */ 211 int mc_csdiscontig; /* chip-selects discontiguous */ 212 uint_t smb_chipid; /* smbios chip instance */ 213 nvlist_t *smb_bboard; /* smbios chip's parent */ 214 }; 215 216 typedef struct mcamd_hdl { 217 int mcamd_errno; 218 int mcamd_debug; 219 } mcamd_hdl_t; 220 221 extern mc_t *mc_list; 222 extern krwlock_t mc_lock; 223 224 extern void mcamd_mkhdl(mcamd_hdl_t *); 225 extern void mcamd_mc_register(cmi_hdl_t, mc_t *); 226 extern void mcamd_ereport_post(mc_t *, const char *, mc_unum_t *, uint64_t); 227 228 /* 229 * mcamd_mc_ops prototypes 230 */ 231 extern cmi_errno_t mcamd_patounum_wrap(void *, uint64_t, uint8_t, uint8_t, 232 uint32_t, int, mc_unum_t *); 233 extern cmi_errno_t mcamd_unumtopa_wrap(void *, mc_unum_t *, nvlist_t *, 234 uint64_t *); 235 236 /* 237 * Internal functions 238 */ 239 cmi_errno_t mcamd_cmierr(int, mcamd_hdl_t *); 240 241 #ifdef __cplusplus 242 } 243 #endif 244 245 #endif /* _MCAMD_H */ 246