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.
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.
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]
21 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22 * Use is subject to license terms.
25 #pragma ident "%Z%%M% %I% %E% SMI"
28 * Given a unum including an offset calculate the associated system
29 * address. This may be different to when the original PA to unum
30 * calculation took place if interleave etc has changed.
33 #include <sys/errno.h>
34 #include <sys/types.h>
37 #include <mcamd_api.h>
38 #include <mcamd_err.h>
41 * The submitted unum must have the MC and DIMM numbers and an offset.
42 * Any cs info it has will not be used - we will reconstruct cs info.
43 * This is because cs is not in the topology used for diagnosis.
46 mcamd_unumtopa(struct mcamd_hdl
*hdl
, mcamd_node_t
*root
, mc_unum_t
*unump
,
49 mcamd_node_t
*mc
, *dimm
;
52 mcamd_dprintf(hdl
, MCAMD_DBG_FLOW
, "mcamd_unumtopa: chip %d "
53 "mc %d dimm %d offset 0x%llx\n", unump
->unum_chip
, unump
->unum_mc
,
54 unump
->unum_dimms
[0], unump
->unum_offset
);
56 if (!MCAMD_RC_OFFSET_VALID(unump
->unum_offset
)) {
57 mcamd_dprintf(hdl
, MCAMD_DBG_FLOW
, "mcamd_unumtopa: offset "
59 return (mcamd_set_errno(hdl
, EMCAMD_NOADDR
));
63 * Search current config for a MC number matching the chip in the
66 for (mc
= mcamd_mc_next(hdl
, root
, NULL
); mc
!= NULL
;
67 mc
= mcamd_mc_next(hdl
, root
, mc
)) {
68 if (!mcamd_get_numprops(hdl
,
69 mc
, MCAMD_PROP_NUM
, &num
,
70 mc
, MCAMD_PROP_DRAMHOLE_SIZE
, &holesz
,
72 mcamd_dprintf(hdl
, MCAMD_DBG_ERR
, "mcamd_unumtopa: "
73 "failed to lookup num, dramhole for MC 0x%p\n", mc
);
74 return (mcamd_set_errno(hdl
, EMCAMD_TREEINVALID
));
76 if (num
== unump
->unum_chip
)
80 mcamd_dprintf(hdl
, MCAMD_DBG_FLOW
, "mcamd_unumtopa; "
81 "no match for MC %d\n", unump
->unum_chip
);
82 return (mcamd_set_errno(hdl
, EMCAMD_NOADDR
));
86 * Search DIMMs of this MC. We can match against the
87 * first dimm in the unum - if there is more than one they all
88 * share the same chip-selects anyway and the pa we will resolve
89 * to is not finer grained than the 128-bits of a dimm pair.
91 for (dimm
= mcamd_dimm_next(hdl
, mc
, NULL
); dimm
!= NULL
;
92 dimm
= mcamd_dimm_next(hdl
, mc
, dimm
)) {
93 if (!mcamd_get_numprop(hdl
, dimm
, MCAMD_PROP_NUM
, &num
)) {
94 mcamd_dprintf(hdl
, MCAMD_DBG_ERR
, "mcamd_unumtopa: "
95 "failed to lookup num for dimm 0xx%p\n",
97 return (mcamd_set_errno(hdl
, EMCAMD_TREEINVALID
));
99 if (num
== unump
->unum_dimms
[0])
103 mcamd_dprintf(hdl
, MCAMD_DBG_FLOW
, "mcamd_unumtopa; "
104 "no match for dimm %d cs %d on MC %d\n",
105 unump
->unum_dimms
[0], unump
->unum_cs
, unump
->unum_chip
);
106 return (mcamd_set_errno(hdl
, EMCAMD_NOADDR
));
109 mcamd_dprintf(hdl
, MCAMD_DBG_FLOW
, "mcamd_unumtopa: matched "
110 "mc 0x%p dimm 0x%p; resolving offset 0x%llx\n",
111 mc
, dimm
, unump
->unum_offset
);
113 if (mc_offset_to_pa(hdl
, mc
, dimm
, unump
->unum_offset
, pa
) < 0) {
114 mcamd_dprintf(hdl
, MCAMD_DBG_FLOW
, "mcamd_unumtopa: "
115 "mc_offset_to_pa failed: %s\n", mcamd_errmsg(hdl
));
116 return (-1); /* errno already set */
119 mcamd_dprintf(hdl
, MCAMD_DBG_FLOW
, "mcamd_unumtopa: "
120 "mc_offset_to_pa succeeded and returned pa=0x%llx: %\n",
124 * If this MC has a dram address hole just below 4GB then we must
125 * hoist all address from the hole start upwards by the hole size
128 if (*pa
>= 0x100000000 - holesz
)
130 mcamd_dprintf(hdl
, MCAMD_DBG_FLOW
, "mcamd_untopa: hoist "
131 "above dram hole of size 0x%llx to get pa=0x%llx",