blob: 19fdbbe9962c438c8e591fc14f15e97835a28d1a [file] [log] [blame]
Frank Vibrans2b4c8312011-02-14 18:30:54 +00001/* $NoKeywords:$ */
2/**
3 * @file
4 *
5 * mmUmaAlloc.c
6 *
7 * Main Memory Feature implementation file for UMA allocation.
8 *
9 * @xrefitem bom "File Content Label" "Release Content"
10 * @e project: AGESA
11 * @e sub-project: (Mem/Main)
12 * @e \$Revision: 35136 $ @e \$Date: 2010-07-16 11:29:48 +0800 (Fri, 16 Jul 2010) $
13 *
14 **/
15/*
16 *****************************************************************************
17 *
18 * Copyright (c) 2011, Advanced Micro Devices, Inc.
19 * All rights reserved.
Edward O'Callaghan1542a6f2014-07-06 19:24:06 +100020 *
Frank Vibrans2b4c8312011-02-14 18:30:54 +000021 * Redistribution and use in source and binary forms, with or without
22 * modification, are permitted provided that the following conditions are met:
23 * * Redistributions of source code must retain the above copyright
24 * notice, this list of conditions and the following disclaimer.
25 * * Redistributions in binary form must reproduce the above copyright
26 * notice, this list of conditions and the following disclaimer in the
27 * documentation and/or other materials provided with the distribution.
Edward O'Callaghan1542a6f2014-07-06 19:24:06 +100028 * * Neither the name of Advanced Micro Devices, Inc. nor the names of
29 * its contributors may be used to endorse or promote products derived
Frank Vibrans2b4c8312011-02-14 18:30:54 +000030 * from this software without specific prior written permission.
Edward O'Callaghan1542a6f2014-07-06 19:24:06 +100031 *
Frank Vibrans2b4c8312011-02-14 18:30:54 +000032 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
33 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
34 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
35 * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
36 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
38 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
39 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
40 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
41 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Edward O'Callaghan1542a6f2014-07-06 19:24:06 +100042 *
Frank Vibrans2b4c8312011-02-14 18:30:54 +000043 * ***************************************************************************
44 *
45 */
46
47/*
48 *----------------------------------------------------------------------------
49 * MODULES USED
50 *
51 *----------------------------------------------------------------------------
52 */
53
54
55#include "AGESA.h"
56#include "amdlib.h"
57#include "heapManager.h"
58#include "OptionMemory.h"
59#include "mm.h"
60#include "mn.h"
61#include "Ids.h"
62#include "mport.h"
63#include "Filecode.h"
64CODE_GROUP (G1_PEICC)
65RDATA_GROUP (G1_PEICC)
66
67#define FILECODE PROC_MEM_MAIN_MMUMAALLOC_FILECODE
68/*----------------------------------------------------------------------------
69 * DEFINITIONS AND MACROS
70 *
71 *----------------------------------------------------------------------------
72 */
73
74/*----------------------------------------------------------------------------
75 * TYPEDEFS AND STRUCTURES
76 *
77 *----------------------------------------------------------------------------
78 */
79
80/*----------------------------------------------------------------------------
81 * PROTOTYPES OF LOCAL FUNCTIONS
82 *
83 *----------------------------------------------------------------------------
84 */
efdesign9884cbce22011-08-04 12:09:17 -060085
86BOOLEAN
87MemMUmaAlloc (
88 IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr
89 );
90
Frank Vibrans2b4c8312011-02-14 18:30:54 +000091/*-----------------------------------------------------------------------------
92* EXPORTED FUNCTIONS
93*
94*-----------------------------------------------------------------------------
95*/
96extern BUILD_OPT_CFG UserOptions;
97
98/* -----------------------------------------------------------------------------*/
99/**
100 *
101 *
102 * UMA allocation mechanism.
103 *
104 * @param[in,out] *MemMainPtr - Pointer to the MEM_MAIN_DATA_BLOCK
105 *
106 */
107BOOLEAN
108MemMUmaAlloc (
109 IN OUT MEM_MAIN_DATA_BLOCK *MemMainPtr
110 )
111{
112 UINT32 TOM;
113 UINT32 TOM2;
114 UINT32 UmaSize;
115 UINT32 TopOfChIntlv;
116 UINT32 DctSelHi;
117 UINT32 UmaAlignment;
118 UINT32 UmaAbove4GBase;
119 UINT32 UmaBelow4GBase;
120 BOOLEAN DctSelIntLvEn;
121 BOOLEAN UmaAbove4GEn;
122 S_UINT64 SMsr;
123 ALLOCATE_HEAP_PARAMS AllocHeapParams;
124 UMA_INFO *UmaInfoPtr;
125
126 MEM_DATA_STRUCT *MemPtr;
127 MEM_NB_BLOCK *NBPtr;
128 MEM_PARAMETER_STRUCT *RefPtr;
129
130 MemPtr = MemMainPtr->MemPtr;
131 NBPtr = &(MemMainPtr->NBPtr[BSP_DIE]);
132 RefPtr = NBPtr->RefPtr;
133
134 TOM2 = 0;
135 SMsr.lo = SMsr.hi = 0;
136 UmaAbove4GBase = 0;
137 RefPtr->UmaBase = 0;
138 UmaAlignment = (UINT32) UserOptions.CfgUmaAlignment;
139 UmaAbove4GEn = UserOptions.CfgUmaAbove4G;
140 DctSelIntLvEn = (NBPtr->GetBitField (NBPtr, BFDctSelIntLvEn) == 1) ? TRUE : FALSE;
141 TopOfChIntlv = NBPtr->GetBitField (NBPtr, BFDctSelBaseAddr) << (27 - 16);
142 DctSelHi = NBPtr->GetBitField (NBPtr, BFDctSelHi);
143
144 // Allocate heap for UMA_INFO
145 AllocHeapParams.RequestedBufferSize = sizeof (UMA_INFO);
146 AllocHeapParams.BufferHandle = AMD_UMA_INFO_HANDLE;
147 AllocHeapParams.Persist = HEAP_SYSTEM_MEM;
148 if (AGESA_SUCCESS != HeapAllocateBuffer (&AllocHeapParams, &MemPtr->StdHeader)) {
149 ASSERT(FALSE); // Could not allocate heap for Uma information.
150 return FALSE;
151 }
152 UmaInfoPtr = (UMA_INFO *) AllocHeapParams.BufferPtr;
153 // Default all the fields of UMA_INFO
154 UmaInfoPtr->UmaMode = (UINT8) UMA_NONE;
155 UmaInfoPtr->UmaSize = 0;
156 UmaInfoPtr->UmaBase = 0;
157 UmaInfoPtr->UmaAttributes = 0;
158 UmaInfoPtr->MemClock = NBPtr->DCTPtr->Timings.TargetSpeed;
159
160 switch (RefPtr->UmaMode) {
161 case UMA_NONE:
162 UmaSize = 0;
163 break;
164 case UMA_SPECIFIED:
165 UmaSize = RefPtr->UmaSize;
166 break;
167 case UMA_AUTO:
168 UmaSize = NBPtr->GetUmaSize (NBPtr);
169 break;
170 default:
171 UmaSize = 0;
172 IDS_ERROR_TRAP;
173 }
174
175 if (UmaSize != 0) {
176 //TOM scaled from [47:0] to [47:16]
177 LibAmdMsrRead (TOP_MEM, (UINT64 *)&SMsr, &(NBPtr->MemPtr->StdHeader));
178 TOM = (SMsr.lo >> 16) | (SMsr.hi << (32 - 16));
179
180 UmaBelow4GBase = (TOM - UmaSize) & UmaAlignment;
181 // Initialize Ref->UmaBase to UmaBelow4GBase
182 RefPtr->UmaBase = UmaBelow4GBase;
183
184 // Uma Above 4G support
185 if (UmaAbove4GEn) {
186 //TOM2 scaled from [47:0] to [47:16]
187 LibAmdMsrRead (TOP_MEM2, (UINT64 *)&SMsr, &(NBPtr->MemPtr->StdHeader));
188 TOM2 = (SMsr.lo >> 16) | (SMsr.hi << (32 - 16));
189 if (TOM2 != 0) {
190 UmaAbove4GBase = (TOM2 - UmaSize) & UmaAlignment;
191 //Set UmaAbove4GBase to 0 if UmaAbove4GBase is below 4GB
192 if (UmaAbove4GBase < _4GB_RJ16) {
193 UmaAbove4GBase = 0;
194 }
195 if (UmaAbove4GBase != 0) {
196 RefPtr->UmaBase = UmaAbove4GBase;
197 // 1. TopOfChIntlv == 0 indicates that whole DCT0 and DCT1 memory are interleaved.
198 // 2. TopOfChIntlv >= TOM tells us :
199 // -All or portion of Uma region that above 4G is NOT interleaved.
200 // -Whole Uma region that below 4G is interleaved.
201 if (DctSelIntLvEn && (TopOfChIntlv >= TOM)) {
202 RefPtr->UmaBase = UmaBelow4GBase;
203 }
204 }
205 }
206 }
207
208 UmaInfoPtr->UmaMode = (UINT8) (RefPtr->UmaMode);
209 UmaInfoPtr->UmaBase = (UINT64) ((UINT64) RefPtr->UmaBase << 16);
210
211 if (RefPtr->UmaBase >= _4GB_RJ16) {
212 // UmaSize might be extended if it is 128MB or 256MB .. aligned, so update it.
213 RefPtr->UmaSize = TOM2 - UmaAbove4GBase;
214 // Uma Typing
215 MemNSetMTRRUmaRegionUCNb (NBPtr, &UmaAbove4GBase, &TOM2);
216 if (DctSelIntLvEn && (TopOfChIntlv == 0)) {
217 UmaInfoPtr->UmaAttributes = UMA_ATTRIBUTE_INTERLEAVE | UMA_ATTRIBUTE_ON_DCT0 | UMA_ATTRIBUTE_ON_DCT1;
218 } else {
219 // Entire UMA region is in the high DCT
220 UmaInfoPtr->UmaAttributes = (DctSelHi == 0) ? UMA_ATTRIBUTE_ON_DCT0 : UMA_ATTRIBUTE_ON_DCT1;
221 }
222 } else {
223 // UmaSize might be extended if it is 128MB or 256MB .. aligned, so update it.
224 RefPtr->UmaSize = TOM - UmaBelow4GBase;
225 // Uma Typing
226 NBPtr->UMAMemTyping (NBPtr);
227 if (DctSelIntLvEn && ((TopOfChIntlv == 0) || (TopOfChIntlv >= TOM))) {
228 UmaInfoPtr->UmaAttributes = UMA_ATTRIBUTE_INTERLEAVE | UMA_ATTRIBUTE_ON_DCT0 | UMA_ATTRIBUTE_ON_DCT1;
229 } else {
230 if (UmaBelow4GBase >= TopOfChIntlv) {
231 // Entire UMA region is in the high DCT
232 UmaInfoPtr->UmaAttributes = (DctSelHi == 0) ? UMA_ATTRIBUTE_ON_DCT0 : UMA_ATTRIBUTE_ON_DCT1;
233 } else if (TopOfChIntlv >= TOM) {
234 // Entire UMA region is in the low DCT
235 UmaInfoPtr->UmaAttributes = (DctSelHi == 1) ? UMA_ATTRIBUTE_ON_DCT0 : UMA_ATTRIBUTE_ON_DCT1;
236 } else {
237 // UMA region is in both DCT0 and DCT1
238 UmaInfoPtr->UmaAttributes = UMA_ATTRIBUTE_ON_DCT0 | UMA_ATTRIBUTE_ON_DCT1;
239 }
240 }
241 }
242 UmaInfoPtr->UmaSize = (RefPtr->UmaSize) << 16;
243 IDS_HDT_CONSOLE (MEM_FLOW, "UMA is allocated:\n\tBase: %x0000\n\tSize: %x0000\n", RefPtr->UmaBase, RefPtr->UmaSize);
244 }
245
246 return TRUE;
247}
248