17aec1d6eScindi /* 27aec1d6eScindi * CDDL HEADER START 37aec1d6eScindi * 47aec1d6eScindi * The contents of this file are subject to the terms of the 58a40a695Sgavinm * Common Development and Distribution License (the "License"). 68a40a695Sgavinm * You may not use this file except in compliance with the License. 77aec1d6eScindi * 87aec1d6eScindi * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97aec1d6eScindi * or http://www.opensolaris.org/os/licensing. 107aec1d6eScindi * See the License for the specific language governing permissions 117aec1d6eScindi * and limitations under the License. 127aec1d6eScindi * 137aec1d6eScindi * When distributing Covered Code, include this CDDL HEADER in each 147aec1d6eScindi * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157aec1d6eScindi * If applicable, add the following below this CDDL HEADER, with the 167aec1d6eScindi * fields enclosed by brackets "[]" replaced with your own identifying 177aec1d6eScindi * information: Portions Copyright [yyyy] [name of copyright owner] 187aec1d6eScindi * 197aec1d6eScindi * CDDL HEADER END 207aec1d6eScindi */ 217aec1d6eScindi 227aec1d6eScindi /* 237aec1d6eScindi * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 247aec1d6eScindi * Use is subject to license terms. 257aec1d6eScindi */ 267aec1d6eScindi 277aec1d6eScindi #ifndef _MCAMD_API_H 287aec1d6eScindi #define _MCAMD_API_H 297aec1d6eScindi 307aec1d6eScindi /* 317aec1d6eScindi * Primary header file for mcamd_* routines in $SRC/common/mc. The 327aec1d6eScindi * routines not implemented there are required to be implemented in the 337aec1d6eScindi * kernel or userland consumer of this interface (such as the mc-amd driver). 347aec1d6eScindi * The common code must use the wrapper functions provided by the consumer 357aec1d6eScindi * to navigate the MC tree, get properties etc. 367aec1d6eScindi */ 377aec1d6eScindi 387aec1d6eScindi #if defined(_KERNEL) 397aec1d6eScindi #include <sys/systm.h> 407aec1d6eScindi #include <sys/sunddi.h> 417aec1d6eScindi #else 427aec1d6eScindi #include <string.h> 437aec1d6eScindi #include <assert.h> 447aec1d6eScindi #endif 457aec1d6eScindi 467aec1d6eScindi #include <sys/types.h> 477aec1d6eScindi #include <sys/mc.h> 487aec1d6eScindi #include <sys/mca_amd.h> 497aec1d6eScindi #include <sys/mc_amd.h> 507aec1d6eScindi 517aec1d6eScindi #ifdef __cplusplus 527aec1d6eScindi extern "C" { 537aec1d6eScindi #endif 547aec1d6eScindi 557aec1d6eScindi /* 567aec1d6eScindi * Consumers of this common code must implement the following types. 577aec1d6eScindi */ 587aec1d6eScindi typedef struct mcamd_node mcamd_node_t; 597aec1d6eScindi struct mcamd_hdl; 607aec1d6eScindi 617aec1d6eScindi /* 628a40a695Sgavinm * Properties and raw register values for an mcamd_node_t are retrieved via 638a40a695Sgavinm * mcamd_get_numprop(s) and mcamd_get_cfgreg(s) specifying a property or 648a40a695Sgavinm * register code below. 657aec1d6eScindi */ 667aec1d6eScindi 678a40a695Sgavinm typedef uint64_t mcamd_prop_t; 688a40a695Sgavinm typedef uint32_t mcamd_cfgreg_t; 697aec1d6eScindi 708a40a695Sgavinm typedef enum mcamd_propcode { 718a40a695Sgavinm /* 728a40a695Sgavinm * Common properties 738a40a695Sgavinm */ 748a40a695Sgavinm MCAMD_PROP_NUM = 0x4000, 757aec1d6eScindi #define MCAMD_PROPSTR_NUM "num" 768a40a695Sgavinm MCAMD_PROP_SIZE, 778a40a695Sgavinm #define MCAMD_PROPSTR_SIZE "size" 788a40a695Sgavinm MCAMD_PROP_BASE_ADDR, 797aec1d6eScindi #define MCAMD_PROPSTR_BASE_ADDR "base-addr" 808a40a695Sgavinm /* 818a40a695Sgavinm * Memory controller properties 828a40a695Sgavinm */ 838a40a695Sgavinm MCAMD_PROP_REV = 0x5000, 848a40a695Sgavinm #define MCAMD_PROPSTR_REV "revision" 858a40a695Sgavinm MCAMD_PROP_LIM_ADDR, 867aec1d6eScindi #define MCAMD_PROPSTR_LIM_ADDR "lim-addr" 878a40a695Sgavinm MCAMD_PROP_ILEN, 888a40a695Sgavinm #define MCAMD_PROPSTR_ILEN "node-ilen" 898a40a695Sgavinm MCAMD_PROP_ILSEL, 908a40a695Sgavinm #define MCAMD_PROPSTR_ILSEL "node-ilsel" 918a40a695Sgavinm MCAMD_PROP_CSINTLVFCTR, 928a40a695Sgavinm #define MCAMD_PROPSTR_CSINTLVFCTR "cs-intlv-factor" 938a40a695Sgavinm MCAMD_PROP_DRAMHOLE_SIZE, 948a40a695Sgavinm #define MCAMD_PROPSTR_DRAMHOLE_SIZE "dram-hole-size" 958a40a695Sgavinm MCAMD_PROP_ACCESS_WIDTH, 967aec1d6eScindi #define MCAMD_PROPSTR_ACCESS_WIDTH "access-width" 978a40a695Sgavinm MCAMD_PROP_CSBANKMAPREG, 988a40a695Sgavinm #define MCAMD_PROPSTR_CSBANKMAPREG "bank-mapping" 998a40a695Sgavinm MCAMD_PROP_BANKSWZL, 1008a40a695Sgavinm #define MCAMD_PROPSTR_BANKSWZL "bankswizzle" 1018a40a695Sgavinm MCAMD_PROP_MOD64MUX, 1028a40a695Sgavinm #define MCAMD_PROPSTR_MOD64MUX "mismatched-dimm-support" 1038a40a695Sgavinm MCAMD_PROP_SPARECS, 1048a40a695Sgavinm #define MCAMD_PROPSTR_SPARECS "spare-csnum" 1058a40a695Sgavinm MCAMD_PROP_BADCS, 1068a40a695Sgavinm #define MCAMD_PROPSTR_BADCS "bad-csnum" 1078a40a695Sgavinm /* 1088a40a695Sgavinm * Chip-select properties 1098a40a695Sgavinm */ 1108a40a695Sgavinm MCAMD_PROP_MASK = 0x6000, 1118a40a695Sgavinm #define MCAMD_PROPSTR_MASK "mask" 1128a40a695Sgavinm MCAMD_PROP_CSBE, 1138a40a695Sgavinm #define MCAMD_PROPSTR_CSBE "cs-bank-enable" 1148a40a695Sgavinm MCAMD_PROP_SPARE, 1158a40a695Sgavinm #define MCAMD_PROPSTR_SPARE "online-spare" 1168a40a695Sgavinm MCAMD_PROP_TESTFAIL, 1178a40a695Sgavinm #define MCAMD_PROPSTR_TESTFAIL "failed-test" 1188a40a695Sgavinm MCAMD_PROP_CSDIMM1, 1198a40a695Sgavinm #define MCAMD_PROPSTR_CSDIMM1 "dimm1-num" 1208a40a695Sgavinm MCAMD_PROP_CSDIMM2, 1218a40a695Sgavinm #define MCAMD_PROPSTR_CSDIMM2 "dimm2-num" 1228a40a695Sgavinm MCAMD_PROP_DIMMRANK 1238a40a695Sgavinm #define MCAMD_PROPSTR_DIMMRANK "dimm-rank" 1248a40a695Sgavinm } mcamd_propcode_t; 1258a40a695Sgavinm 1268a40a695Sgavinm typedef enum mcamd_regcode { 1278a40a695Sgavinm MCAMD_REG_DRAMBASE = 0x7000, 1288a40a695Sgavinm MCAMD_REG_DRAMLIMIT, 1298a40a695Sgavinm MCAMD_REG_DRAMHOLE, 1308a40a695Sgavinm MCAMD_REG_DRAMCFGLO, 1318a40a695Sgavinm MCAMD_REG_DRAMCFGHI, 1328a40a695Sgavinm MCAMD_REG_CSBASE, 1338a40a695Sgavinm MCAMD_REG_CSMASK 1348a40a695Sgavinm } mcamd_regcode_t; 1357aec1d6eScindi /* 1367aec1d6eScindi * Flags for mcamd_dprintf 1377aec1d6eScindi */ 1387aec1d6eScindi #define MCAMD_DBG_ERR 0x1 1397aec1d6eScindi #define MCAMD_DBG_FLOW 0x2 1407aec1d6eScindi 1417aec1d6eScindi typedef union mcamd_dimm_offset_un mcamd_dimm_offset_un_t; 1427aec1d6eScindi 1437aec1d6eScindi /* 1447aec1d6eScindi * Offset definition. Encode everything in a single uint64_t, allowing some 1457aec1d6eScindi * room for growth in numbers of rows/columns/banks in future MC revisions. 1467aec1d6eScindi * Some consumers will handle this as an opaque uint64 to be passed around, 1478a40a695Sgavinm * while others will want to look inside via the union defined below. Since 1488a40a695Sgavinm * we must support a 32-bit kernel we structure this as two uint32_t. 1497aec1d6eScindi */ 1507aec1d6eScindi 1517aec1d6eScindi #define MCAMD_OFFSET_VERSION_0 0x0 1527aec1d6eScindi #define MCAMD_OFFSET_VERSION MCAMD_OFFSET_VERSION_0 1537aec1d6eScindi 1547aec1d6eScindi union mcamd_dimm_offset_un { 1557aec1d6eScindi uint64_t _dou_offset; 1567aec1d6eScindi struct { 1577aec1d6eScindi struct { 1587aec1d6eScindi uint32_t dou_col:20; /* column address */ 1597aec1d6eScindi uint32_t dou_bank:4; /* internal sdram bank number */ 1607aec1d6eScindi uint32_t unused:8; 1617aec1d6eScindi } lo; 1627aec1d6eScindi struct { 1637aec1d6eScindi uint32_t dou_row:20; /* row address */ 1647aec1d6eScindi uint32_t dou_rank:3; /* cs rank on dimm */ 1657aec1d6eScindi uint32_t unused:4; 1667aec1d6eScindi uint32_t dou_version:4; /* offset encoding version */ 1677aec1d6eScindi uint32_t dou_valid:1; /* set if valid */ 1687aec1d6eScindi } hi; 1697aec1d6eScindi } _dou_hilo; 1707aec1d6eScindi }; 1717aec1d6eScindi 1727aec1d6eScindi #define do_offset _dou_offset 1737aec1d6eScindi 1747aec1d6eScindi #define do_valid _dou_hilo.hi.dou_valid 1757aec1d6eScindi #define do_version _dou_hilo.hi.dou_version 1767aec1d6eScindi #define do_rank _dou_hilo.hi.dou_rank 1777aec1d6eScindi #define do_row _dou_hilo.hi.dou_row 1787aec1d6eScindi #define do_bank _dou_hilo.lo.dou_bank 1797aec1d6eScindi #define do_col _dou_hilo.lo.dou_col 1807aec1d6eScindi 1817aec1d6eScindi /* 1827aec1d6eScindi * The following work on an offset treated as a uint64_t. 1837aec1d6eScindi */ 1847aec1d6eScindi #define MCAMD_RC_OFFSET_VALID(offset) (((uint64_t)(offset) & (1ULL << 63)) != 0) 1857aec1d6eScindi #define MCAMD_RC_OFFSET_VERSION(offset) (((uint64_t)offset >> 59) & 0xf) 1867aec1d6eScindi 1877aec1d6eScindi /* 1887aec1d6eScindi * Value to be used to indicate an invalid offset. 1897aec1d6eScindi */ 1907aec1d6eScindi #define MCAMD_RC_INVALID_OFFSET 0x0 1917aec1d6eScindi 1927aec1d6eScindi /* 1937aec1d6eScindi * Routines provided by the common mcamd code. 1947aec1d6eScindi */ 1958a40a695Sgavinm extern const char *mcamd_get_propname(mcamd_propcode_t); 1967aec1d6eScindi 1977aec1d6eScindi extern int mcamd_patounum(struct mcamd_hdl *, mcamd_node_t *, uint64_t, 198*4156fc34Sgavinm uint8_t, uint8_t, uint32_t, int, mc_unum_t *); 1998a40a695Sgavinm extern int mcamd_unumtopa(struct mcamd_hdl *, mcamd_node_t *, mc_unum_t *, 2007aec1d6eScindi uint64_t *); 2018a40a695Sgavinm extern int mc_pa_to_offset(struct mcamd_hdl *, mcamd_node_t *, mcamd_node_t *, 2028a40a695Sgavinm uint64_t, uint64_t *); 2038a40a695Sgavinm extern int mc_offset_to_pa(struct mcamd_hdl *, mcamd_node_t *, mcamd_node_t *, 2048a40a695Sgavinm uint64_t, uint64_t *); 2057aec1d6eScindi 2067aec1d6eScindi extern int mcamd_cs_size(struct mcamd_hdl *, mcamd_node_t *, int, size_t *); 2077aec1d6eScindi 2087aec1d6eScindi extern int mcamd_synd_validate(struct mcamd_hdl *, uint32_t, int); 2097aec1d6eScindi extern int mcamd_eccsynd_decode(struct mcamd_hdl *, uint32_t, uint_t *); 2107aec1d6eScindi extern int mcamd_cksynd_decode(struct mcamd_hdl *, uint32_t, uint_t *, 2117aec1d6eScindi uint_t *); 2127aec1d6eScindi extern int mcamd_cksym_decode(struct mcamd_hdl *, uint_t, int *, int *, 2137aec1d6eScindi int *, int *); 2147aec1d6eScindi 2157aec1d6eScindi extern void *mcamd_set_errno_ptr(struct mcamd_hdl *, int); 2167aec1d6eScindi extern const char *mcamd_strerror(int); 2177aec1d6eScindi extern const char *mcamd_errmsg(struct mcamd_hdl *); 2187aec1d6eScindi 2197aec1d6eScindi /* 2207aec1d6eScindi * Routines to be provided by wrapper code. 2217aec1d6eScindi */ 2227aec1d6eScindi extern mcamd_node_t *mcamd_mc_next(struct mcamd_hdl *, mcamd_node_t *, 2237aec1d6eScindi mcamd_node_t *); 2247aec1d6eScindi extern mcamd_node_t *mcamd_cs_next(struct mcamd_hdl *, mcamd_node_t *, 2257aec1d6eScindi mcamd_node_t *); 2267aec1d6eScindi extern mcamd_node_t *mcamd_dimm_next(struct mcamd_hdl *, mcamd_node_t *, 2277aec1d6eScindi mcamd_node_t *); 2287aec1d6eScindi 2297aec1d6eScindi extern mcamd_node_t *mcamd_cs_mc(struct mcamd_hdl *, mcamd_node_t *); 2307aec1d6eScindi extern mcamd_node_t *mcamd_dimm_mc(struct mcamd_hdl *, mcamd_node_t *); 2317aec1d6eScindi 2328a40a695Sgavinm extern int mcamd_get_numprop(struct mcamd_hdl *, mcamd_node_t *, 2338a40a695Sgavinm mcamd_propcode_t, mcamd_prop_t *); 2348a40a695Sgavinm extern int mcamd_get_numprops(struct mcamd_hdl *, ...); 2358a40a695Sgavinm extern int mcamd_get_cfgreg(struct mcamd_hdl *, mcamd_node_t *, 2368a40a695Sgavinm mcamd_regcode_t, mcamd_cfgreg_t *); 2378a40a695Sgavinm extern int mcamd_get_cfgregs(struct mcamd_hdl *, ...); 2387aec1d6eScindi 2397aec1d6eScindi extern int mcamd_errno(struct mcamd_hdl *); 2407aec1d6eScindi extern int mcamd_set_errno(struct mcamd_hdl *, int); 2417aec1d6eScindi extern void mcamd_dprintf(struct mcamd_hdl *, int, const char *, ...); 2427aec1d6eScindi 2437aec1d6eScindi #ifdef __cplusplus 2447aec1d6eScindi } 2457aec1d6eScindi #endif 2467aec1d6eScindi 2477aec1d6eScindi #endif /* _MCAMD_API_H */ 248