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 #pragma ident "%Z%%M% %I% %E% SMI" 317aec1d6eScindi 327aec1d6eScindi /* 337aec1d6eScindi * Primary header file for mcamd_* routines in $SRC/common/mc. The 347aec1d6eScindi * routines not implemented there are required to be implemented in the 357aec1d6eScindi * kernel or userland consumer of this interface (such as the mc-amd driver). 367aec1d6eScindi * The common code must use the wrapper functions provided by the consumer 377aec1d6eScindi * to navigate the MC tree, get properties etc. 387aec1d6eScindi */ 397aec1d6eScindi 407aec1d6eScindi #if defined(_KERNEL) 417aec1d6eScindi #include <sys/systm.h> 427aec1d6eScindi #include <sys/sunddi.h> 437aec1d6eScindi #else 447aec1d6eScindi #include <string.h> 457aec1d6eScindi #include <assert.h> 467aec1d6eScindi #endif 477aec1d6eScindi 487aec1d6eScindi #include <sys/types.h> 497aec1d6eScindi #include <sys/mc.h> 507aec1d6eScindi #include <sys/mca_amd.h> 517aec1d6eScindi #include <sys/mc_amd.h> 527aec1d6eScindi 537aec1d6eScindi #ifdef __cplusplus 547aec1d6eScindi extern "C" { 557aec1d6eScindi #endif 567aec1d6eScindi 577aec1d6eScindi /* 587aec1d6eScindi * Consumers of this common code must implement the following types. 597aec1d6eScindi */ 607aec1d6eScindi typedef struct mcamd_node mcamd_node_t; 617aec1d6eScindi struct mcamd_hdl; 627aec1d6eScindi 637aec1d6eScindi /* 648a40a695Sgavinm * Properties and raw register values for an mcamd_node_t are retrieved via 658a40a695Sgavinm * mcamd_get_numprop(s) and mcamd_get_cfgreg(s) specifying a property or 668a40a695Sgavinm * register code below. 677aec1d6eScindi */ 687aec1d6eScindi 698a40a695Sgavinm typedef uint64_t mcamd_prop_t; 708a40a695Sgavinm typedef uint32_t mcamd_cfgreg_t; 717aec1d6eScindi 728a40a695Sgavinm typedef enum mcamd_propcode { 738a40a695Sgavinm /* 748a40a695Sgavinm * Common properties 758a40a695Sgavinm */ 768a40a695Sgavinm MCAMD_PROP_NUM = 0x4000, 777aec1d6eScindi #define MCAMD_PROPSTR_NUM "num" 788a40a695Sgavinm MCAMD_PROP_SIZE, 797aec1d6eScindi #define MCAMD_PROPSTR_SIZE "size" 808a40a695Sgavinm MCAMD_PROP_BASE_ADDR, 818a40a695Sgavinm #define MCAMD_PROPSTR_BASE_ADDR "base-addr" 828a40a695Sgavinm /* 838a40a695Sgavinm * Memory controller properties 848a40a695Sgavinm */ 858a40a695Sgavinm MCAMD_PROP_REV = 0x5000, 867aec1d6eScindi #define MCAMD_PROPSTR_REV "revision" 878a40a695Sgavinm MCAMD_PROP_LIM_ADDR, 888a40a695Sgavinm #define MCAMD_PROPSTR_LIM_ADDR "lim-addr" 898a40a695Sgavinm MCAMD_PROP_ILEN, 908a40a695Sgavinm #define MCAMD_PROPSTR_ILEN "node-ilen" 918a40a695Sgavinm MCAMD_PROP_ILSEL, 928a40a695Sgavinm #define MCAMD_PROPSTR_ILSEL "node-ilsel" 938a40a695Sgavinm MCAMD_PROP_CSINTLVFCTR, 948a40a695Sgavinm #define MCAMD_PROPSTR_CSINTLVFCTR "cs-intlv-factor" 958a40a695Sgavinm MCAMD_PROP_DRAMHOLE_SIZE, 968a40a695Sgavinm #define MCAMD_PROPSTR_DRAMHOLE_SIZE "dram-hole-size" 978a40a695Sgavinm MCAMD_PROP_ACCESS_WIDTH, 988a40a695Sgavinm #define MCAMD_PROPSTR_ACCESS_WIDTH "access-width" 998a40a695Sgavinm MCAMD_PROP_CSBANKMAPREG, 1008a40a695Sgavinm #define MCAMD_PROPSTR_CSBANKMAPREG "bank-mapping" 1018a40a695Sgavinm MCAMD_PROP_BANKSWZL, 1028a40a695Sgavinm #define MCAMD_PROPSTR_BANKSWZL "bankswizzle" 1038a40a695Sgavinm MCAMD_PROP_MOD64MUX, 1048a40a695Sgavinm #define MCAMD_PROPSTR_MOD64MUX "mismatched-dimm-support" 1058a40a695Sgavinm MCAMD_PROP_SPARECS, 1068a40a695Sgavinm #define MCAMD_PROPSTR_SPARECS "spare-csnum" 1078a40a695Sgavinm MCAMD_PROP_BADCS, 1088a40a695Sgavinm #define MCAMD_PROPSTR_BADCS "bad-csnum" 1098a40a695Sgavinm /* 1108a40a695Sgavinm * Chip-select properties 1118a40a695Sgavinm */ 1128a40a695Sgavinm MCAMD_PROP_MASK = 0x6000, 1138a40a695Sgavinm #define MCAMD_PROPSTR_MASK "mask" 1148a40a695Sgavinm MCAMD_PROP_CSBE, 1158a40a695Sgavinm #define MCAMD_PROPSTR_CSBE "cs-bank-enable" 1168a40a695Sgavinm MCAMD_PROP_SPARE, 1178a40a695Sgavinm #define MCAMD_PROPSTR_SPARE "online-spare" 1188a40a695Sgavinm MCAMD_PROP_TESTFAIL, 1198a40a695Sgavinm #define MCAMD_PROPSTR_TESTFAIL "failed-test" 1208a40a695Sgavinm MCAMD_PROP_CSDIMM1, 1218a40a695Sgavinm #define MCAMD_PROPSTR_CSDIMM1 "dimm1-num" 1228a40a695Sgavinm MCAMD_PROP_CSDIMM2, 1238a40a695Sgavinm #define MCAMD_PROPSTR_CSDIMM2 "dimm2-num" 1248a40a695Sgavinm MCAMD_PROP_DIMMRANK 1258a40a695Sgavinm #define MCAMD_PROPSTR_DIMMRANK "dimm-rank" 1268a40a695Sgavinm } mcamd_propcode_t; 1277aec1d6eScindi 1288a40a695Sgavinm typedef enum mcamd_regcode { 1298a40a695Sgavinm MCAMD_REG_DRAMBASE = 0x7000, 1308a40a695Sgavinm MCAMD_REG_DRAMLIMIT, 1318a40a695Sgavinm MCAMD_REG_DRAMHOLE, 1328a40a695Sgavinm MCAMD_REG_DRAMCFGLO, 1338a40a695Sgavinm MCAMD_REG_DRAMCFGHI, 1348a40a695Sgavinm MCAMD_REG_CSBASE, 1358a40a695Sgavinm MCAMD_REG_CSMASK 1368a40a695Sgavinm } mcamd_regcode_t; 1377aec1d6eScindi /* 1387aec1d6eScindi * Flags for mcamd_dprintf 1397aec1d6eScindi */ 1407aec1d6eScindi #define MCAMD_DBG_ERR 0x1 1417aec1d6eScindi #define MCAMD_DBG_FLOW 0x2 1427aec1d6eScindi 1437aec1d6eScindi typedef union mcamd_dimm_offset_un mcamd_dimm_offset_un_t; 1447aec1d6eScindi 1457aec1d6eScindi /* 1467aec1d6eScindi * Offset definition. Encode everything in a single uint64_t, allowing some 1477aec1d6eScindi * room for growth in numbers of rows/columns/banks in future MC revisions. 1487aec1d6eScindi * Some consumers will handle this as an opaque uint64 to be passed around, 1498a40a695Sgavinm * while others will want to look inside via the union defined below. Since 1508a40a695Sgavinm * we must support a 32-bit kernel we structure this as two uint32_t. 1517aec1d6eScindi */ 1527aec1d6eScindi 1537aec1d6eScindi #define MCAMD_OFFSET_VERSION_0 0x0 1547aec1d6eScindi #define MCAMD_OFFSET_VERSION MCAMD_OFFSET_VERSION_0 1557aec1d6eScindi 1567aec1d6eScindi union mcamd_dimm_offset_un { 1577aec1d6eScindi uint64_t _dou_offset; 1587aec1d6eScindi struct { 1597aec1d6eScindi struct { 1607aec1d6eScindi uint32_t dou_col:20; /* column address */ 1617aec1d6eScindi uint32_t dou_bank:4; /* internal sdram bank number */ 1627aec1d6eScindi uint32_t unused:8; 1637aec1d6eScindi } lo; 1647aec1d6eScindi struct { 1657aec1d6eScindi uint32_t dou_row:20; /* row address */ 1667aec1d6eScindi uint32_t dou_rank:3; /* cs rank on dimm */ 1677aec1d6eScindi uint32_t unused:4; 1687aec1d6eScindi uint32_t dou_version:4; /* offset encoding version */ 1697aec1d6eScindi uint32_t dou_valid:1; /* set if valid */ 1707aec1d6eScindi } hi; 1717aec1d6eScindi } _dou_hilo; 1727aec1d6eScindi }; 1737aec1d6eScindi 1747aec1d6eScindi #define do_offset _dou_offset 1757aec1d6eScindi 1767aec1d6eScindi #define do_valid _dou_hilo.hi.dou_valid 1777aec1d6eScindi #define do_version _dou_hilo.hi.dou_version 1787aec1d6eScindi #define do_rank _dou_hilo.hi.dou_rank 1797aec1d6eScindi #define do_row _dou_hilo.hi.dou_row 1807aec1d6eScindi #define do_bank _dou_hilo.lo.dou_bank 1817aec1d6eScindi #define do_col _dou_hilo.lo.dou_col 1827aec1d6eScindi 1837aec1d6eScindi /* 1847aec1d6eScindi * The following work on an offset treated as a uint64_t. 1857aec1d6eScindi */ 1867aec1d6eScindi #define MCAMD_RC_OFFSET_VALID(offset) (((uint64_t)(offset) & (1ULL << 63)) != 0) 1877aec1d6eScindi #define MCAMD_RC_OFFSET_VERSION(offset) (((uint64_t)offset >> 59) & 0xf) 1887aec1d6eScindi 1897aec1d6eScindi /* 1907aec1d6eScindi * Value to be used to indicate an invalid offset. 1917aec1d6eScindi */ 1927aec1d6eScindi #define MCAMD_RC_INVALID_OFFSET 0x0 1937aec1d6eScindi 1947aec1d6eScindi /* 1957aec1d6eScindi * Routines provided by the common mcamd code. 1967aec1d6eScindi */ 1978a40a695Sgavinm extern const char *mcamd_get_propname(mcamd_propcode_t); 1987aec1d6eScindi 1997aec1d6eScindi extern int mcamd_patounum(struct mcamd_hdl *, mcamd_node_t *, uint64_t, 200*4156fc34Sgavinm uint8_t, uint8_t, uint32_t, int, mc_unum_t *); 2018a40a695Sgavinm extern int mcamd_unumtopa(struct mcamd_hdl *, mcamd_node_t *, mc_unum_t *, 2027aec1d6eScindi uint64_t *); 2038a40a695Sgavinm extern int mc_pa_to_offset(struct mcamd_hdl *, mcamd_node_t *, mcamd_node_t *, 2048a40a695Sgavinm uint64_t, uint64_t *); 2058a40a695Sgavinm extern int mc_offset_to_pa(struct mcamd_hdl *, mcamd_node_t *, mcamd_node_t *, 2068a40a695Sgavinm uint64_t, uint64_t *); 2077aec1d6eScindi 2087aec1d6eScindi extern int mcamd_cs_size(struct mcamd_hdl *, mcamd_node_t *, int, size_t *); 2097aec1d6eScindi 2107aec1d6eScindi extern int mcamd_synd_validate(struct mcamd_hdl *, uint32_t, int); 2117aec1d6eScindi extern int mcamd_eccsynd_decode(struct mcamd_hdl *, uint32_t, uint_t *); 2127aec1d6eScindi extern int mcamd_cksynd_decode(struct mcamd_hdl *, uint32_t, uint_t *, 2137aec1d6eScindi uint_t *); 2147aec1d6eScindi extern int mcamd_cksym_decode(struct mcamd_hdl *, uint_t, int *, int *, 2157aec1d6eScindi int *, int *); 2167aec1d6eScindi 2177aec1d6eScindi extern void *mcamd_set_errno_ptr(struct mcamd_hdl *, int); 2187aec1d6eScindi extern const char *mcamd_strerror(int); 2197aec1d6eScindi extern const char *mcamd_errmsg(struct mcamd_hdl *); 2207aec1d6eScindi 2217aec1d6eScindi /* 2227aec1d6eScindi * Routines to be provided by wrapper code. 2237aec1d6eScindi */ 2247aec1d6eScindi extern mcamd_node_t *mcamd_mc_next(struct mcamd_hdl *, mcamd_node_t *, 2257aec1d6eScindi mcamd_node_t *); 2267aec1d6eScindi extern mcamd_node_t *mcamd_cs_next(struct mcamd_hdl *, mcamd_node_t *, 2277aec1d6eScindi mcamd_node_t *); 2287aec1d6eScindi extern mcamd_node_t *mcamd_dimm_next(struct mcamd_hdl *, mcamd_node_t *, 2297aec1d6eScindi mcamd_node_t *); 2307aec1d6eScindi 2317aec1d6eScindi extern mcamd_node_t *mcamd_cs_mc(struct mcamd_hdl *, mcamd_node_t *); 2327aec1d6eScindi extern mcamd_node_t *mcamd_dimm_mc(struct mcamd_hdl *, mcamd_node_t *); 2337aec1d6eScindi 2348a40a695Sgavinm extern int mcamd_get_numprop(struct mcamd_hdl *, mcamd_node_t *, 2358a40a695Sgavinm mcamd_propcode_t, mcamd_prop_t *); 2368a40a695Sgavinm extern int mcamd_get_numprops(struct mcamd_hdl *, ...); 2378a40a695Sgavinm extern int mcamd_get_cfgreg(struct mcamd_hdl *, mcamd_node_t *, 2388a40a695Sgavinm mcamd_regcode_t, mcamd_cfgreg_t *); 2398a40a695Sgavinm extern int mcamd_get_cfgregs(struct mcamd_hdl *, ...); 2407aec1d6eScindi 2417aec1d6eScindi extern int mcamd_errno(struct mcamd_hdl *); 2427aec1d6eScindi extern int mcamd_set_errno(struct mcamd_hdl *, int); 2437aec1d6eScindi extern void mcamd_dprintf(struct mcamd_hdl *, int, const char *, ...); 2447aec1d6eScindi 2457aec1d6eScindi #ifdef __cplusplus 2467aec1d6eScindi } 2477aec1d6eScindi #endif 2487aec1d6eScindi 2497aec1d6eScindi #endif /* _MCAMD_API_H */ 250