AGESA F15: AMD family15 AGESA code
[coreboot.git] / src / vendorcode / amd / agesa / f15 / Legacy / Proc / arch2008.asm
1 ;*****************************************************************************
2 ; AMD Generic Encapsulated Software Architecture
3 ;
4 ;  Workfile: arch2008.asm     $Revision: 50871 $    $Date: 2011-04-14 15:39:51 -0600 (Thu, 14 Apr 2011) $
5 ;
6 ; Description: ARCH2008.ASM - AGESA Architecture 2008 Wrapper Template
7 ;
8 ;*****************************************************************************
9 ;
10 ; Copyright (C) 2012 Advanced Micro Devices, Inc.
11 ; All rights reserved.
12 ;
13 ; Redistribution and use in source and binary forms, with or without
14 ; modification, are permitted provided that the following conditions are met:
15 ;     * Redistributions of source code must retain the above copyright
16 ;       notice, this list of conditions and the following disclaimer.
17 ;     * Redistributions in binary form must reproduce the above copyright
18 ;       notice, this list of conditions and the following disclaimer in the
19 ;       documentation and/or other materials provided with the distribution.
20 ;     * Neither the name of Advanced Micro Devices, Inc. nor the names of
21 ;       its contributors may be used to endorse or promote products derived
22 ;       from this software without specific prior written permission.
23 ;
24 ; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
25 ; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26 ; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 ; DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
28 ; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29 ; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 ; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31 ; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 ; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 ; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 ;
35 ;*****************************************************************************
36
37     .XLIST
38     INCLUDE agesa.inc
39     INCLUDE acwrapg.inc       ; Necessary support file as part of wrapper, including but not limited to segment start/end macros.
40     INCLUDE acwrap.inc        ; IBVs may specify host BIOS-specific include files required when building.
41     INCLUDE cpcarmac.inc
42     INCLUDE bridge32.inc
43     .LIST
44     .586p
45     .mmx
46
47
48 ;----------------------------------------------------------------------------
49 ; Local definitions
50 ;----------------------------------------------------------------------------
51
52 sOemCallout STRUCT
53     FuncName   DD   ?         ; Call out function name
54     FuncPtr    DW   ?         ; Call out function pointer
55 sOemCallout ENDS
56
57 sOemEventHandler STRUCT
58     ClassCode  DD   ?         ; AGESA event log sub-class code
59     FuncPtr    DW   ?         ; Event handler function pointer
60 sOemEventHandler ENDS
61
62 ;; A typical legacy BIOS implementation may require the E000 and F000 segments
63 ;; to be cached.
64 EXE_CACHE_REGION_BASE_0  EQU  0E0000h
65 EXE_CACHE_REGION_SIZE_0  EQU  20000h
66
67 ;; In this sample implementation, the B1 and B2 images are placed next to each
68 ;; other in the BIOS ROM to help with the maximization of cached code.
69 EXE_CACHE_REGION_BASE_1  EQU  AGESA_B1_ADDRESS
70 EXE_CACHE_REGION_SIZE_1  EQU  40000h
71
72 ;; The third region is not needed in our example.
73 EXE_CACHE_REGION_BASE_2  EQU  0
74 EXE_CACHE_REGION_SIZE_2  EQU  0
75
76
77 ;----------------------------------------------------------------------------
78 ;    PERSISTENT SEGMENT
79 ; This segment is required to be present throughout all BIOS execution.
80 ;----------------------------------------------------------------------------
81
82 AMD_PERSISTENT_START
83
84
85 ;----------------------------------------------------------------------------
86 ; Instantiate the global descriptor table
87 ;----------------------------------------------------------------------------
88
89 AMD_BRIDGE_32_GDT AMD_GDT         ; Instantiate the global descriptor table
90                                   ; required by the push-high mechanism.
91
92
93 ;----------------------------------------------------------------------------
94 ; Declare the external routines required in the persistent segment
95 ;----------------------------------------------------------------------------
96
97 ;+-------------------------------------------------------------------------
98 ;
99 ;   AmdDfltRet
100 ;
101 ;   Entry:
102 ;     None
103 ;
104 ;   Exit:
105 ;     None
106 ;
107 ;   Modified:
108 ;     None
109 ;
110 ;   Purpose:
111 ;     Near stub procedure.  Simply perform a retn instruction.
112 ;
113 EXTERN AmdDfltRet:NEAR
114
115
116 ;+-------------------------------------------------------------------------
117 ;
118 ;   AmdDfltRetFar
119 ;
120 ;   Entry:
121 ;     None
122 ;
123 ;   Exit:
124 ;     None
125 ;
126 ;   Modified:
127 ;     None
128 ;
129 ;   Purpose:
130 ;     Far stub procedure.  Simply perform a retf instruction.
131 ;
132 EXTERN AmdDfltRetFar:FAR
133
134
135 ;----------------------------------------------------------------------------
136 ; Declare the optional external routines in the persistent segment
137 ;----------------------------------------------------------------------------
138
139 ;+---------------------------------------------------------------------------
140 ;
141 ;   myModuleTypeMismatchHandler (Example)
142 ;
143 ;   Entry:
144 ;     ESI - Pointer to the EVENT_PARAMS structure of the failure.
145 ;     [ESI].DataParam1 - Socket
146 ;     [ESI].DataParam2 - DCT
147 ;     [ESI].DataParam3 - Channel
148 ;     [ESI].DataParam4 - 0x00000000
149 ;
150 ;   Exit:
151 ;     None
152 ;
153 ;   Modified:
154 ;     None
155 ;
156 ;   Purpose:
157 ;     This procedure can be used to react to a memory module type
158 ;     mismatch error discovered by the AGESA code.  Actions taken
159 ;     may include, but are not limited to:
160 ;       Logging the event to NV for display later
161 ;       Reset, excluding the mismatch on subsequent reboot
162 ;       Do nothing
163 ;
164 ;   Dependencies:
165 ;     None
166 ;
167 EXTERN myModuleTypeMismatchHandler(AmdDfltRet):NEAR
168
169 ;+---------------------------------------------------------------------------
170 ;
171 ;   oemPlatformConfigInit (Optional)
172 ;
173 ;   Entry:
174 ;     EDI - 32-bit flat pointer to the PLATFORM_CONFIGURATION to be
175 ;           passed in to the next AGESA entry point.
176 ;
177 ;           typedef struct {
178 ;             IN PERFORMANCE_PROFILE PlatformProfile;
179 ;             IN CPU_HT_DEEMPHASIS_LEVEL *PlatformDeemphasisList;
180 ;             IN UINT8               CoreLevelingMode;
181 ;             IN PLATFORM_C1E_MODES  C1eMode;
182 ;             IN UINT32              C1ePlatformData;
183 ;             IN UINT32              C1ePlatformData1;
184 ;             IN UINT32              C1ePlatformData2;
185 ;             IN UINT32              C1ePlatformData3;
186 ;             IN BOOLEAN             UserOptionDmi;
187 ;             IN BOOLEAN             UserOptionPState;
188 ;             IN BOOLEAN             UserOptionSrat;
189 ;             IN BOOLEAN             UserOptionSlit;
190 ;             IN BOOLEAN             UserOptionWhea;
191 ;             IN UINT32              PowerCeiling;
192 ;             IN BOOLEAN             PstateIndependent;
193 ;           } PLATFORM_CONFIGURATION;
194 ;
195 ;           typedef struct {
196 ;             IN UINT8 Socket;
197 ;             IN UINT8 Link;
198 ;             IN UINT8 LoFreq;
199 ;             IN UINT8 HighFreq;
200 ;             IN PLATFORM_DEEMPHASIS_LEVEL     ReceiverDeemphasis;
201 ;             IN PLATFORM_DEEMPHASIS_LEVEL     DcvDeemphasis;
202 ;           } CPU_HT_DEEMPHASIS_LEVEL;
203 ;
204 ;           typedef struct {
205 ;             IN PLATFORM_CONTROL_FLOW PlatformControlFlowMode;
206 ;             IN BOOLEAN               UseHtAssist;
207 ;             IN BOOLEAN               UseAtmMode;
208 ;             IN BOOLEAN               Use32ByteRefresh;
209 ;             IN BOOLEAN               UseVariableMctIsocPriority;
210 ;           } PERFORMANCE_PROFILE;
211 ;
212 ;   Exit:
213 ;     None
214 ;
215 ;   Modified:
216 ;     None
217 ;
218 ;   Purpose:
219 ;     Provide a single hook routine to modify the parameters of a
220 ;     PLATFORM_CONFIGURATION structure before any entry point that
221 ;     has such a structure as an input.
222 ;
223 ;   Dependencies:
224 ;     None
225 ;
226 ;   Example:
227 ;     If your platform is running in UMA mode, the following code
228 ;     may be added:
229 ;       mov  (PLATFORM_CONFIGURATION PTR [edi]).PlatformProfile.PlatformControlFlowMode, UmaDr
230 ;
231 EXTERN oemPlatformConfigInit(AmdDfltRetFar):FAR
232
233 ;+---------------------------------------------------------------------------
234 ;
235 ;   oemCallout (Optional)
236 ;
237 ;   Entry:
238 ;     ECX - Callout function number
239 ;     EDX - Function-specific UINTN
240 ;     ESI - Pointer to function specific data
241 ;
242 ;   Exit:
243 ;     EAX - Contains the AGESA_STATUS return code.
244 ;
245 ;   Modified:
246 ;     None
247 ;
248 ;   Purpose:
249 ;     The default call out router function which resides in the same
250 ;     segment as the push-high bridge code.
251 ;
252 ;   Dependencies:
253 ;     None
254 ;
255 EXTERN oemCallout(AmdDfltRet):NEAR
256
257
258 ;----------------------------------------------------------------------------
259 ; Define the sample wrapper routines for the persistent segment
260 ;----------------------------------------------------------------------------
261
262 ;+---------------------------------------------------------------------------
263 ;
264 ;   AmdBridge32
265 ;
266 ;   Entry:
267 ;     EDX - A Real Mode FAR pointer using seg16:Offset16 format that
268 ;           points to a local host environment call-out router. If
269 ;           this pointer is not equal to zero, then this pointer is
270 ;           used as the call-out router instead of the standard
271 ;           OemCallout. This may be useful when the call-out router
272 ;           is not located in the same segment as the AmdBridge32 and
273 ;           AmdCallout16 routines.
274 ;     ESI - A Flat Mode pointer (32-bit address) that points to the
275 ;           configuration block (AMD_CONFIG_PARAMS) for the AGESA
276 ;           software function.
277 ;
278 ;   Exit:
279 ;     EAX - Contains the AGESA_STATUS return code.
280 ;
281 ;   Modified:
282 ;     None
283 ;
284 ;   Purpose:
285 ;     Execute an AGESA software function through the Push-High interface.
286 ;
287 ;   Dependencies:
288 ;     This procedure requires a stack. The host environment must use the
289 ;     provided service function to establish the stack environment prior
290 ;     to making the call to this procedure.
291 ;
292 AmdBridge32 PROC FAR PUBLIC
293     AMD_BRIDGE_32 AMD_GDT             ; use the macro for the body
294     ret
295 AmdBridge32 ENDP
296
297
298 ;+---------------------------------------------------------------------------
299 ;
300 ;   AmdEnableStack
301 ;
302 ;   Entry:
303 ;     BX - Return address
304 ;
305 ;   Exit:
306 ;     EAX - Contains the AGESA_STATUS return code.
307 ;     SS:ESP - Points to the private stack location for this processor core.
308 ;     ECX - Upon success, contains this processor core's stack size in bytes.
309 ;
310 ;   Modified:
311 ;     EAX, ECX, EDX, EDI, ESI, ESP, DS, ES
312 ;
313 ;   Purpose:
314 ;     This procedure is used to establish the stack within the host environment.
315 ;
316 ;   Dependencies:
317 ;     The host environment must use this procedure and not rely on any other
318 ;     sources to create the stack region.
319 ;
320 AmdEnableStack PROC NEAR PUBLIC
321     AMD_ENABLE_STACK
322     ;; EAX = AGESA_SUCCESS, The stack space has been allocated for this core.
323     ;; EAX = AGESA_WARNING, The stack has already been set up.  SS:ESP is set
324     ;;       to stack top, and ECX is the stack size in bytes.
325     jmp   bx
326 AmdEnableStack ENDP
327
328
329 ;+---------------------------------------------------------------------------
330 ;
331 ;   AmdDisableStack
332 ;
333 ;   Entry:
334 ;     BX - Return address
335 ;
336 ;   Exit:
337 ;     EAX - Contains the AGESA_STATUS return code.
338 ;
339 ;   Modified:
340 ;     EAX, ECX, EDX, ESI, ESP
341 ;
342 ;   Purpose:
343 ;     This procedure is used to remove the pre-memory stack from within the
344 ;     host environment.
345 ;     The exit state for the BSP is described as follows:
346 ;       Memory region 00000-9FFFF MTRRS are set as WB memory.
347 ;       Processor Cache is enabled (CD bit is cleared).
348 ;       MTRRs used for execution cache are kept.
349 ;       Cache content is flushed (invalidated without write-back).
350 ;       Any family-specific clean-up done.
351 ;     The exit state for the APs is described as follows:
352 ;       Memory region 00000-9FFFF MTRRS are set as WB memory.
353 ;       Memory region A0000-DFFFF MTRRS are set as UC IO.
354 ;       Memory region E0000-FFFFF MTRRS are set as UC memory.
355 ;       MTRRs used for execution cache are cleared.
356 ;       Processor Cache is disabled (CD bit is set).
357 ;       Top-of-Memory (TOM) set to the system top of memory as determined
358 ;         by the memory initialization routines.
359 ;       System lock command is enabled.
360 ;       Any family-specific clean-up done.
361 ;
362 ;   Dependencies:
363 ;     The host environment must use this procedure and not rely on any other
364 ;     sources to break down the stack region.
365 ;     If executing in 16-bit code, the host environment must establish the
366 ;     "Big Real" mode of 32-bit addressing of data.
367 ;
368 AmdDisableStack PROC NEAR PUBLIC
369     AMD_DISABLE_STACK
370     ;; EAX = AGESA_SUCCESS, The stack space has been disabled for this core.
371     jmp   bx
372 AmdDisableStack ENDP
373
374
375 ;+---------------------------------------------------------------------------
376 ;
377 ;   AmdCallout16
378 ;
379 ;   Entry:
380 ;     [esp+8] - Func
381 ;     [esp+12] - Data
382 ;     [esp+16] - Configuration Block
383 ;     [esp+4] - Return address to AGESA
384 ;
385 ;   Exit:
386 ;     EAX - Contains the AGESA_STATUS return code.
387 ;
388 ;   Modified:
389 ;     None
390 ;
391 ;   Purpose:
392 ;     Execute callback from the push-high interface.
393 ;
394 ;   Dependencies:
395 ;     None
396 ;
397 AmdCallout16 PROC FAR PUBLIC ; declare the procedure
398     AMD_CALLOUT_16 oemCallout ; use the macro for the body
399     ret
400 AmdCallout16 ENDP
401
402
403 ;+---------------------------------------------------------------------------
404 ;
405 ;   AmdProcessAgesaErrors (Optional)
406 ;
407 ;   Entry:
408 ;     AL - Heap status of the AGESA entry point that was just invoked.
409 ;     EBX - AGESA image base address.
410 ;     EDX - Segment / Offset of the appropriate callout router function.
411 ;
412 ;   Exit:
413 ;     None
414 ;
415 ;   Modified:
416 ;     None
417 ;
418 ;   Purpose:
419 ;     This procedure is used to handle any errors that may have occurred
420 ;     during an AGESA entry point.
421 ;
422 ;   Dependencies:
423 ;     None
424 ;
425 AmdProcessAgesaErrors PROC FAR PUBLIC
426     LOCAL localCpuInterfaceBlock:EVENT_PARAMS
427
428     pushad
429     xor   edi, edi
430     mov   di, ss
431     shl   edi, 4
432     lea   esi, localCpuInterfaceBlock
433     add   esi, edi
434
435     ; Fill default config block
436     mov   (EVENT_PARAMS PTR [esi]).StdHeader.Func, AMD_READ_EVENT_LOG
437     mov   (EVENT_PARAMS PTR [esi]).StdHeader.ImageBasePtr, ebx
438     mov   (EVENT_PARAMS PTR [esi]).StdHeader.AltImageBasePtr, 0
439     mov   (EVENT_PARAMS PTR [esi]).StdHeader.HeapStatus, al
440     mov   edi, SEG AmdCallout16
441     shl   edi, 4
442     add   edi, OFFSET AmdCallout16
443     mov   (EVENT_PARAMS PTR [esi]).StdHeader.CalloutPtr, edi
444
445     ; Flush the event log searching for, and handling all monitored events
446     xor   eax, eax
447     .while (eax == 0)
448         push  edx
449         call  AmdBridge32
450         pop   edx
451         .if (eax == AGESA_SUCCESS)
452             mov   eax, (EVENT_PARAMS PTR [esi]).EventInfo
453             .if (eax != 0)
454                 lea   di, cs:AgesaEventTable
455
456 loopThruTable:
457                 cmp   di, OFFSET cs:AgesaEventTableEnd
458                 jae   unhandledEvent
459
460                 cmp   eax, cs:[di].sOemEventHandler.ClassCode
461                 je    FoundMatch
462                 add   di, SIZEOF sOemEventHandler
463                 jmp   loopThruTable
464
465 FoundMatch:
466                 mov   bx, cs:[di].sOemEventHandler.FuncPtr
467                 call  bx
468
469 unhandledEvent:
470                 xor   eax, eax
471             .else
472                 mov   al, 1
473             .endif
474         .endif
475     .endw
476     popad
477     ret
478
479 AmdProcessAgesaErrors ENDP
480
481
482 ;----------------------------------------------------------------------------
483 ; Define the error handler table
484 ;----------------------------------------------------------------------------
485
486 AgesaEventTable LABEL BYTE
487     ;; Add entries as desired
488     ;;---------
489     ;; EXAMPLE
490     ;;---------
491     sOemEventHandler <MEM_ERROR_MODULE_TYPE_MISMATCH_DIMM, OFFSET myModuleTypeMismatchHandler>
492 AgesaEventTableEnd LABEL BYTE
493
494
495 AMD_PERSISTENT_END
496
497
498
499
500 ;----------------------------------------------------------------------------
501 ;    RECOVERY SEGMENT
502 ; This segment resides in the classic 'boot-block,' and is used
503 ; for recovery.
504 ;----------------------------------------------------------------------------
505
506 AMD_RECOVERY_START
507
508
509 ;----------------------------------------------------------------------------
510 ; Declare the external routines required in the recovery segment
511 ;----------------------------------------------------------------------------
512
513 ;+---------------------------------------------------------------------------
514 ;
515 ;   myReadSPDRecovery (Required for proper recovery mode operation)
516 ;
517 ;   Entry:
518 ;     ESI - Pointer to an AGESA_READ_SPD_PARAMS structure.
519 ;
520 ;     typedef struct {
521 ;       IN OUT AMD_CONFIG_PARAMS StdHeader;
522 ;       IN       UINT8 SocketId;
523 ;       IN       UINT8 MemChannelId;
524 ;       IN       UINT8 DimmId;
525 ;       IN OUT   UINT8 *Buffer;
526 ;       IN OUT   MEM_DATA_STRUCT *MemData;
527 ;     } AGESA_READ_SPD_PARAMS;
528 ;
529 ;   Exit:
530 ;     EAX - Contains the AGESA_STATUS return code.
531 ;           AGESA_SUCCESS Indicates the SPD block for the indicated
532 ;                         DIMM was read successfully.
533 ;           AGESA_BOUNDS_CHK The specified DIMM is not present.
534 ;           AGESA_UNSUPPORTED This is a required function, so this
535 ;                             value being returned causes a critical
536 ;                             error response value from the AGESA
537 ;                             software function and no memory initialized.
538 ;           AGESA_ERROR The DIMM SPD read process has generated
539 ;                       communication errors.
540 ;
541 ;   Modified:
542 ;     None
543 ;
544 ;   Purpose:
545 ;     This call out reads a block of memory SPD data and places it
546 ;     into the provided buffer.
547 ;
548 ;   Dependencies:
549 ;     None
550 ;
551 EXTERN myReadSPDRecovery:NEAR
552
553
554 ;----------------------------------------------------------------------------
555 ; Define the sample wrapper routines for the recovery segment
556 ;----------------------------------------------------------------------------
557
558 ;+---------------------------------------------------------------------------
559 ;
560 ;   AmdInitResetWrapper
561 ;
562 ;   Entry:
563 ;     DS - 0000 with 4 gigabyte access
564 ;     ES - 0000 with 4 gigabyte access
565 ;
566 ;   Exit:
567 ;     None
568 ;
569 ;   Modified:
570 ;     None
571 ;
572 ;   Purpose:
573 ;     A minimal initialization of the processor core is performed. This
574 ;     procedure must be called by all processor cores. The code path
575 ;     separates the BSP from the APs and performs a separate and appropriate
576 ;     list of tasks for each class of core.
577 ;     For the BSP, the following actions are performed:
578 ;       Internal heap sub-system initialization
579 ;       Primary non-coherent HyperTransportT link initialization
580 ;       Return to the host environment to test for Recovery Mode.
581 ;     The AP processor cores do not participate in the recovery process.
582 ;     However, they execute this routine after being released to execute
583 ;     by the BSP during the main boot process. Their actions include the
584 ;     following:
585 ;       Internal heap sub-system initialization
586 ;       Proceed to a wait loop waiting for commands from the BSP
587 ;
588 ;     For the cache regions, up to three regions of execution cache can be
589 ;     allocated following the following rules:
590 ;     1. Once a region is allocated, it cannot be de-allocated. However, it
591 ;        can be expanded.
592 ;     2. At most, two of the three regions can be located above 1 MByte. A
593 ;        region failing this rule is ignored.
594 ;     3. All region addresses must be at or above the 0x000D0000 linear
595 ;        address. A region failing this rule is ignored.
596 ;     4. The address is aligned on a 32-KByte boundary. Starting addresses
597 ;        is rounded down to the nearest 32-Kbyte boundary.
598 ;     5. The execution cache size must be a multiple of 32 KByte. Size is
599 ;        rounded up to the next multiple of 32 KByte.
600 ;     6. A region must not span either the 1-MByte boundary or the 4-GByte
601 ;        boundary. Allocated size is truncated to not span the boundary.
602 ;     7. The granted cached execution regions, address, and size are calculated
603 ;        based on the available cache resources of the processor core.
604 ;        Allocations are made up to the limit of cache available on the
605 ;        installed processor.
606 ;     Warning: Enabling instruction cache outside of this interface can cause
607 ;              data corruption.
608 ;
609 ;   Dependencies:
610 ;     This procedure is expected to be executed soon after a system reset
611 ;     for the main boot path or resume path of execution.
612 ;
613 ;     This procedure requires a stack.
614 ;
615 ;     Because the heap system is not yet operational at the point of the
616 ;     interface call, the host environment must allocate the storage for
617 ;     the AMD_RESET_PARAMS structure before making the first call to
618 ;     AmdCreateStruct.  This is the ByHost method of allocation.
619 ;
620 AmdInitResetWrapper PROC NEAR PUBLIC
621     local localCfgBlock:AMD_INTERFACE_PARAMS
622     local localResetParams:AMD_RESET_PARAMS
623
624     pushad
625
626     ; Prepare for the call to initialize the input parameters for AmdInitReset
627     xor   eax, eax
628     mov   ax, ss
629     shl   eax, 4
630     lea   esi, localCfgBlock
631     add   esi, eax
632     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.ImageBasePtr, AGESA_B1_ADDRESS
633     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_CREATE_STRUCT
634     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.AltImageBasePtr, 0
635     mov   edx, SEG AmdCallout16
636     shl   edx, 4
637     add   edx, OFFSET AmdCallout16
638     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.CalloutPtr, edx
639
640     ; Use the 'ByHost' allocation method because the heap has not been initialized as of yet.
641     mov   (AMD_INTERFACE_PARAMS ptr [esi]).AgesaFunctionName, AMD_INIT_RESET
642     mov   (AMD_INTERFACE_PARAMS ptr [esi]).AllocationMethod, ByHost
643     mov   (AMD_INTERFACE_PARAMS ptr [esi]).NewStructSize, sizeof AMD_RESET_PARAMS
644     lea   edx, localResetParams
645     add   edx, eax
646     push  edx
647     mov   (AMD_INTERFACE_PARAMS ptr [esi]).NewStructPtr, edx
648     mov   dx, SEG AmdCalloutRouterRecovery
649     shl   edx, 16
650     mov   dx, OFFSET AmdCalloutRouterRecovery
651     push  edx
652     call  AmdBridge32
653     pop   edx
654     pop   esi
655
656     ; The structure has been initialized.  Now modify the default settings as desired.
657
658     ; Allocate the execution cache to maximize the amount of code in ROM that is cached.
659     ; Placing the B1 and B2 images near one another is a good way to ensure the AGESA code
660     ; is cached.
661     mov   (AMD_RESET_PARAMS ptr [esi]).CacheRegion.ExeCacheStartAddr, EXE_CACHE_REGION_BASE_0
662     mov   (AMD_RESET_PARAMS ptr [esi]).CacheRegion.ExeCacheSize, EXE_CACHE_REGION_SIZE_0
663     mov   (AMD_RESET_PARAMS ptr [esi + sizeof EXECUTION_CACHE_REGION]).CacheRegion.ExeCacheStartAddr, EXE_CACHE_REGION_BASE_1
664     mov   (AMD_RESET_PARAMS ptr [esi + sizeof EXECUTION_CACHE_REGION]).CacheRegion.ExeCacheSize, EXE_CACHE_REGION_SIZE_1
665     mov   (AMD_RESET_PARAMS ptr [esi + (2 * sizeof EXECUTION_CACHE_REGION)]).CacheRegion.ExeCacheStartAddr, EXE_CACHE_REGION_BASE_2
666     mov   (AMD_RESET_PARAMS ptr [esi + (2 * sizeof EXECUTION_CACHE_REGION)]).CacheRegion.ExeCacheSize, EXE_CACHE_REGION_SIZE_2
667
668     ; Call in to the AmdInitReset entry point
669     push  edx
670     call  AmdBridge32
671     pop   edx
672
673     ;;  EAX = AGESA_STATUS
674     ;;  AGESA_SUCCESS Early initialization completed successfully.
675     ;;  AGESA_WARNING One or more of the execution cache allocation
676     ;;                rules were violated, but an adjustment was made
677     ;;                and space was allocated.
678     ;;  AGESA_ERROR One or more of the execution cache allocation rules
679     ;;              were violated, which resulted in a requested cache
680     ;;              region to not be allocated.
681     ;;              The storage space allocated for the AMD_RESET_PARAMS
682     ;;              structure is insufficient.
683
684     .if (eax != AGESA_SUCCESS)
685         mov   al, (AMD_RESET_PARAMS ptr [esi]).StdHeader.HeapStatus
686         mov   ebx, AGESA_B1_ADDRESS
687         call  AmdProcessAgesaErrors
688     .endif
689
690
691     ;; Here are what the MTRRs should look like based off of the CacheRegions specified above:
692
693     ;; Fixed-Range MTRRs
694     ;; Name                 Address         Value
695     ;; ----------------     --------        ----------------
696     ;; MTRRfix4k_E0000      0000026C        0505050505050505
697     ;; MTRRfix4k_E8000      0000026D        0505050505050505
698     ;; MTRRfix4k_F0000      0000026E        0505050505050505
699     ;; MTRRfix4k_F8000      0000026F        0505050505050505
700     ;; MTRRdefType          000002FF        0000000000000C00
701     ;;
702     ;; Variable-Range MTRRs and IO Range
703     ;;       MTRRphysBase(n)             MTRRphysMask(n)
704     ;;       -----------------           -----------------
705     ;; n=0   0000000000000000            0000000000000000
706     ;; n=1   0000000000000000            0000000000000000
707     ;; n=2   0000000000000000            0000000000000000
708     ;; n=3   0000000000000000            0000000000000000
709     ;; n=4   0000000000000000            0000000000000000
710     ;; n=5   Heap Base (Varies by core)  0000FFFFFFFF0800
711     ;; n=6   AGESA_B1_ADDRESS | 6        0000FFFFFFFC0800
712     ;; n=7   0000000000000000            0000000000000000
713
714
715     ;; Because the allocation method is 'ByHost,' the call to AMD_RELEASE_STRUCT is
716     ;; not necessary.  Stack space reclamation is left up to the host BIOS.
717
718     popad
719     ret
720
721
722 AmdInitResetWrapper ENDP
723
724
725 ;+---------------------------------------------------------------------------
726 ;
727 ;   AmdInitRecoveryWrapper
728 ;
729 ;   Entry:
730 ;     DS - 0000 with 4 gigabyte access
731 ;     ES - 0000 with 4 gigabyte access
732 ;
733 ;   Exit:
734 ;     None
735 ;
736 ;   Modified:
737 ;     None
738 ;
739 ;   Purpose:
740 ;     Perform a minimum initialization of the processor and memory to
741 ;     support a recovery mode flash ROM update.
742 ;     For the BSP, the following actions are performed:
743 ;       Configuration of CPU core for recovery process
744 ;       Minimal initialization of some memory
745 ;     The AP processor cores do not participate in the recovery process.
746 ;     No actions or tasks are performed by the AP cores for this time point.
747 ;
748 ;   Dependencies:
749 ;     This procedure requires a stack. The host environment must use one of
750 ;     the provided service functions to establish the stack environment prior
751 ;     to making the call to this procedure.
752 ;
753 AmdInitRecoveryWrapper PROC NEAR PUBLIC
754     local localCfgBlock:AMD_INTERFACE_PARAMS
755
756     pushad
757
758     ; Prepare for the call to create and initialize the input parameters for AmdInitRecovery
759     xor   eax, eax
760     mov   ax, ss
761     shl   eax, 4
762     lea   esi, localCfgBlock
763     add   esi, eax
764     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.ImageBasePtr, AGESA_B1_ADDRESS
765     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_CREATE_STRUCT
766     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.AltImageBasePtr, 0
767     mov   edx, SEG AmdCallout16
768     shl   edx, 4
769     add   edx, OFFSET AmdCallout16
770     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.CalloutPtr, edx
771
772     mov   (AMD_INTERFACE_PARAMS ptr [esi]).AgesaFunctionName, AMD_INIT_RECOVERY
773     mov   (AMD_INTERFACE_PARAMS ptr [esi]).AllocationMethod, PreMemHeap
774     mov   (AMD_INTERFACE_PARAMS ptr [esi]).NewStructSize, 0
775     push  esi
776     mov   dx, SEG AmdCalloutRouterRecovery
777     shl   edx, 16
778     mov   dx, OFFSET AmdCalloutRouterRecovery
779     push  edx
780     call  AmdBridge32
781     pop   edx
782
783     mov   esi, (AMD_INTERFACE_PARAMS ptr [esi]).NewStructPtr
784
785     ; The structure has been initialized.  Now modify the default settings as desired.
786
787
788     ; Call in to the AmdInitRecovery entry point
789     push  edx
790     call  AmdBridge32
791     pop   edx
792
793     ;;  EAX = AGESA_STATUS
794     ;;  AGESA_SUCCESS The function has completed successfully.
795     ;;  AGESA_WARNING One or more of the allocation rules were violated,
796     ;;                but an adjustment was made and space was allocated.
797     ;;  AGESA_ERROR One or more of the allocation rules were violated,
798     ;;              which resulted in a requested cache region to not be
799     ;;              allocated.
800     ;;  AGESA_FATAL No memory was found in the system.
801
802     .if (eax != AGESA_SUCCESS)
803         mov   al, (AMD_RECOVERY_PARAMS ptr [esi]).StdHeader.HeapStatus
804         mov   ebx, AGESA_B1_ADDRESS
805         call  AmdProcessAgesaErrors
806     .endif
807
808     ; Allow AGESA to free the space used by AmdInitRecovery
809     pop   esi
810     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_RELEASE_STRUCT
811     call  AmdBridge32
812
813     popad
814     ret
815 AmdInitRecoveryWrapper ENDP
816
817
818 ;+---------------------------------------------------------------------------
819 ;
820 ;   AmdCalloutRouterRecovery
821 ;
822 ;   Entry:
823 ;     ECX - Callout function number
824 ;     EDX - Function-specific UINTN
825 ;     ESI - Pointer to function specific data
826 ;
827 ;   Exit:
828 ;     EAX - Contains the AGESA_STATUS return code.
829 ;
830 ;   Modified:
831 ;     None
832 ;
833 ;   Purpose:
834 ;     The call out router function for AmdInitReset and
835 ;     AmdInitRecovery.
836 ;
837 ;   Dependencies:
838 ;     None
839 ;
840 AmdCalloutRouterRecovery PROC FAR PUBLIC USES ECX EBX ESI BX DI DS ES
841     xor   ax, ax
842     mov   ds, ax
843     mov   es, ax
844     lea   di, cs:CalloutRouterTableRecovery
845     mov   eax, AGESA_UNSUPPORTED
846
847 loopThruTable:
848     cmp   di, OFFSET cs:CalloutRouterTableRecoveryEnd
849     jae   amdCpuCalloutExit ; exit with AGESA_UNSUPPORTED
850     cmp   ecx, cs:[di].sOemCallout.FuncName
851     je    FoundMatch
852     add   di, SIZEOF sOemCallout
853     jmp   loopThruTable
854
855 FoundMatch:
856     mov   bx, cs:[di].sOemCallout.FuncPtr
857     call  bx
858
859 amdCpuCalloutExit:
860     ret
861 AmdCalloutRouterRecovery ENDP
862
863
864 ;----------------------------------------------------------------------------
865 ; Define the callout dispatch table for the recovery segment
866 ;----------------------------------------------------------------------------
867
868 CalloutRouterTableRecovery LABEL BYTE
869     ;; Standard B1 implementations only need the SPD reader call out function to be implemented.
870     sOemCallout <AGESA_READ_SPD, OFFSET myReadSPDRecovery>
871 CalloutRouterTableRecoveryEnd LABEL BYTE
872
873
874 AMD_RECOVERY_END
875
876
877
878 ;----------------------------------------------------------------------------
879 ;    PRE-MEMORY SEGMENT
880 ; This segment must be uncompressed in the ROM image.
881 ;----------------------------------------------------------------------------
882
883 AMD_PREMEM_START
884
885
886 ;----------------------------------------------------------------------------
887 ; Declare the external routines required in the recovery segment
888 ;----------------------------------------------------------------------------
889
890 ;+---------------------------------------------------------------------------
891 ;
892 ;   myReadSPDPremem (Required)
893 ;
894 ;   Entry:
895 ;     ESI - Pointer to an AGESA_READ_SPD_PARAMS structure
896 ;
897 ;     typedef struct {
898 ;       IN OUT AMD_CONFIG_PARAMS StdHeader;
899 ;       IN       UINT8 SocketId;
900 ;       IN       UINT8 MemChannelId;
901 ;       IN       UINT8 DimmId;
902 ;       IN OUT   UINT8 *Buffer;
903 ;       IN OUT   MEM_DATA_STRUCT *MemData;
904 ;     } AGESA_READ_SPD_PARAMS;
905 ;
906 ;   Exit:
907 ;     EAX - Contains the AGESA_STATUS return code.
908 ;           AGESA_SUCCESS Indicates the SPD block for the indicated
909 ;                         DIMM was read successfully.
910 ;           AGESA_BOUNDS_CHK The specified DIMM is not present.
911 ;           AGESA_UNSUPPORTED This is a required function, so this
912 ;                             value being returned causes a critical
913 ;                             error response value from the AGESA
914 ;                             software function and no memory initialized.
915 ;           AGESA_ERROR The DIMM SPD read process has generated
916 ;                       communication errors.
917 ;
918 ;   Modified:
919 ;     None
920 ;
921 ;   Purpose:
922 ;     This call out reads a block of memory SPD data and places it
923 ;     into the provided buffer.
924 ;
925 ;   Dependencies:
926 ;     None
927 ;
928 EXTERN myReadSPDPremem:NEAR
929
930 ;+-------------------------------------------------------------------------
931 ;
932 ;   AmdDfltRetPremem
933 ;
934 ;   Entry:
935 ;     None
936 ;
937 ;   Exit:
938 ;     None
939 ;
940 ;   Modified:
941 ;     None
942 ;
943 ;   Purpose:
944 ;     Near stub procedure in the prememory segment.  Simply perform a
945 ;     retn instruction.
946 ;
947 EXTERN AmdDfltRetPremem:NEAR
948
949 ;+---------------------------------------------------------------------------
950 ;
951 ;   myDoReset (Required)
952 ;
953 ;   Entry:
954 ;     EDX - Reset type
955 ;           1 - Warm reset whenever
956 ;           2 - Cold reset whenever
957 ;           3 - Warm reset immediately
958 ;           4 - Cold reset immediately
959 ;     ESI - Pointer to an AMD_CONFIG_PARAMS structure.
960 ;
961 ;   Exit:
962 ;     EAX - Contains the AGESA_STATUS return code.
963 ;           AGESA_SUCCESS The function has completed successfully.
964 ;           AGESA_UNSUPPORTED This is a required function, so this
965 ;                             value being returned causes a critical
966 ;                             error response value from the AGESA
967 ;                             software function.
968 ;
969 ;   Modified:
970 ;     None
971 ;
972 ;   Purpose:
973 ;     This host environment function must initiate the specified type
974 ;     of system reset.
975 ;
976 ;     Implementation of this function by the host environment is
977 ;     REQUIRED. Some host environments may record this as a request
978 ;     allowing other elements in the system to perform some additional
979 ;     tasks before the actual reset is issued.
980 ;
981 ;   Dependencies:
982 ;     The AMD processor contains 3 bits (BiosRstDet[2:0]) in a PCI
983 ;     register (F0x6C Link Initialization Control Register) that
984 ;     indicate the reset status. These bits are reserved for use by
985 ;     the AGESA software and should not be modified by the host
986 ;     environment.
987 ;
988 EXTERN myDoReset:NEAR
989
990
991 ;+---------------------------------------------------------------------------
992 ;
993 ;   myGetNonVolatileS3Context (Required for proper S3 operation)
994 ;
995 ;   Entry:
996 ;     None
997 ;
998 ;   Exit:
999 ;     EBX - Pointer to the non-volatile S3 context block
1000 ;     ECX - Size in bytes of the non-volatile S3 context block
1001 ;
1002 ;   Modified:
1003 ;     None
1004 ;
1005 ;   Purpose:
1006 ;     The host environment must return the pointer to the data
1007 ;     saved during the mySaveNonVolatileS3Context routine.
1008 ;
1009 ;   Dependencies:
1010 ;     None
1011 ;
1012 EXTERN myGetNonVolatileS3Context:NEAR
1013
1014
1015 ;----------------------------------------------------------------------------
1016 ; Declare the optional external routines in the prememory segment
1017 ;----------------------------------------------------------------------------
1018
1019 ;+---------------------------------------------------------------------------
1020 ;
1021 ;   myAgesaHookBeforeExitSelfRefresh (Optional)
1022 ;
1023 ;   Entry:
1024 ;     Prior to this hook, AGESA will display - AGESA_TESTPOINT - 44h
1025 ;     ESI - Pointer to a data structure containing the memory information
1026 ;
1027 ;   Exit:
1028 ;     After returning control to AGESA, AGESA will display: - AGESA_TESTPOINT - 45h
1029 ;     EAX - Contains the AGESA_STATUS return code
1030 ;           AGESA_SUCCESS The function has completed successfully
1031 ;           AGESA_UNSUPPORTED This function is not implemented by the host environment
1032 ;           AGESA_WARNING A non-critical issue has occued in the host environment
1033 ;
1034 ;   Modified:
1035 ;     None
1036 ;
1037 ;   Purpose:
1038 ;     General purpose hook called before the exiting self refresh
1039 ;     This procedure is called once per channel
1040 ;
1041 ;     Implementation of this function is optional for the host environment
1042 ;     This call-out is an opportunity for the host environment to make dynamic
1043 ;     modifications to the memory timing settings specific to the board or host
1044 ;     environment before exiting self refresh on S3 resume
1045 ;
1046 ;   Dependencies:
1047 ;     This procedure is called before the exit self refresh bit is set in the resume
1048 ;     sequence. The host environment must initiate the OS restart process. This procedure
1049 ;     requires a stack. The host environment must establish the stack environment prior
1050 ;     to making the call to this procedure
1051 ;
1052 EXTERN myAgesaHookBeforeExitSelfRefresh(AmdDfltRetPremem):NEAR
1053
1054
1055 ;+---------------------------------------------------------------------------
1056 ;
1057 ;   myHookBeforeDramInit (Optional)
1058 ;
1059 ;   Entry:
1060 ;     Prior to this hook, AGESA will display - AGESA_TESTPOINT - 40h
1061 ;     ESI - Pointer to a data structure containing the memory information
1062 ;
1063 ;   Exit:
1064 ;     After returning control to AGESA, AGESA will display - AGESA_TESTPOINT - 41h
1065 ;     EAX - Contains the AGESA_STATUS return code.
1066 ;           AGESA_SUCCESS The function has completed successfully.
1067 ;           AGESA_UNSUPPORTED This function is not implemented by the host environment
1068 ;
1069 ;   Modified:
1070 ;     None
1071 ;
1072 ;   Purpose:
1073 ;     General-purpose hook called before the DRAM_Init bit is set. Called
1074 ;     once per MCT
1075 ;
1076 ;     Implementation of this function is optional for the host environment
1077 ;     This call-out is an opportunity for the host environment to make
1078 ;     dynamic modifications to the memory timing settings specific to the
1079 ;     board or host environment
1080 ;
1081 ;   Dependencies:
1082 ;     None
1083 ;
1084 EXTERN myHookBeforeDramInit(AmdDfltRetPremem):NEAR
1085
1086
1087 ;+---------------------------------------------------------------------------
1088 ;
1089 ;   myHookBeforeDQSTraining (Optional)
1090 ;
1091 ;   Entry:
1092 ;     Prior to this hook, AGESA will display - AGESA_TESTPOINT - 42h
1093 ;     ESI - Pointer to a data structure containing the memory information.
1094 ;
1095 ;   Exit:
1096 ;     After returning control to AGESA, AGESA will display - AGESA_TESTPOINT - 43h
1097 ;     EAX - Contains the AGESA_STATUS return code.
1098 ;           AGESA_SUCCESS The function has completed successfully.
1099 ;           AGESA_UNSUPPORTED This function is not implemented by the
1100 ;                             host environment.
1101 ;
1102 ;   Modified:
1103 ;     None
1104 ;
1105 ;   Purpose:
1106 ;     General-purpose hook called just before the memory training processes
1107 ;     begin. Called once per MCT.
1108 ;
1109 ;     Implementation of this function is optional for the host environment.
1110 ;     This call-out is an opportunity for the host environment to make
1111 ;     dynamic modifications to the memory timing settings specific to the
1112 ;     board or host environment.
1113 ;
1114 ;     The host environment may also use this call-out for some board-
1115 ;     specific features that should be activated at this time point,
1116 ;     such as:
1117 ;       Low voltage DIMMs-the host environment should set the recommended
1118 ;       voltages found in the memory data structure for each memory
1119 ;       channel. This needs to occur before training begins.
1120 ;
1121 ;   Dependencies:
1122 ;     None
1123 ;
1124 EXTERN myHookBeforeDQSTraining(AmdDfltRetPremem):NEAR
1125
1126
1127 ;----------------------------------------------------------------------------
1128 ; Define the sample wrapper routines for the prememory segment
1129 ;----------------------------------------------------------------------------
1130
1131 ;+---------------------------------------------------------------------------
1132 ;
1133 ;   AmdInitEarlyWrapper
1134 ;
1135 ;   Entry:
1136 ;     On Entry to "AmdInitEarly" AGESA will display AGESA_TESTPOINT - C4h
1137 ;     DS - 0000 with 4 gigabyte access
1138 ;     ES - 0000 with 4 gigabyte access
1139 ;
1140 ;   Exit:
1141 ;     On Exit from "AmdInitEarly" AGESA will display AGESA_TESTPOINT - C5h
1142 ;     None
1143 ;
1144 ;   Modified:
1145 ;     None
1146 ;
1147 ;   Purpose:
1148 ;     A full initialization of the processor is performed. Action details
1149 ;     differ for the BSP and AP processor cores.
1150 ;     For the BSP, the following actions are performed:
1151 ;       Full HyperTransportT link initialization, coherent and non-coherent
1152 ;       Processor register loading
1153 ;       Microcode patch load
1154 ;       Errata workaround processing
1155 ;       Launch all processor cores
1156 ;       Configure the processor power management capabilities
1157 ;       Request a warm reset if needed
1158 ;     For the AP, the following actions are performed:
1159 ;       Processor register loading
1160 ;       Microcode patch load
1161 ;       Errata workaround processing
1162 ;       Configure the processor power management capabilities
1163 ;
1164 ;   Dependencies:
1165 ;     This procedure is expected to be called before main memory initialization
1166 ;     and before the system warm reset. Prior to this, the basic configuration
1167 ;     done by the AmdInitReset routine must be completed.
1168 ;
1169 ;     This procedure requires a stack. The host environment must use one of the
1170 ;     provided service functions to establish the stack environment prior to
1171 ;     making the call to this procedure.
1172 ;
1173 ;     The processes performed at this time point require communication between
1174 ;     processor cores.
1175 ;
1176 ;     The host environment must recognize that all processor cores are running
1177 ;     in parallel and avoid activities that might interfere with the core-to-core
1178 ;     communication, such as modifying the MTRR settings or writing to the APIC
1179 ;     registers.
1180 ;
1181 AmdInitEarlyWrapper PROC NEAR PUBLIC
1182     local localCfgBlock:AMD_INTERFACE_PARAMS
1183
1184     pushad
1185
1186     ; Prepare for the call to create and initialize the input parameters for AmdInitEarly
1187     xor   eax, eax
1188     mov   ax, ss
1189     shl   eax, 4
1190     lea   esi, localCfgBlock
1191     add   esi, eax
1192     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.ImageBasePtr, AGESA_B2_ADDRESS
1193     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_CREATE_STRUCT
1194     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.AltImageBasePtr, 0
1195     mov   edx, SEG AmdCallout16
1196     shl   edx, 4
1197     add   edx, OFFSET AmdCallout16
1198     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.CalloutPtr, edx
1199
1200     mov   (AMD_INTERFACE_PARAMS ptr [esi]).AgesaFunctionName, AMD_INIT_EARLY
1201     mov   (AMD_INTERFACE_PARAMS ptr [esi]).AllocationMethod, PreMemHeap
1202     mov   (AMD_INTERFACE_PARAMS ptr [esi]).NewStructSize, 0
1203     push  esi
1204     mov   dx, SEG AmdCalloutRouterPremem
1205     shl   edx, 16
1206     mov   dx, OFFSET AmdCalloutRouterPremem
1207     push  edx
1208     call  AmdBridge32
1209     pop   edx
1210
1211     mov   esi, (AMD_INTERFACE_PARAMS ptr [esi]).NewStructPtr
1212
1213     ; The structure has been initialized.  Now modify the default settings as desired.
1214
1215     mov   edi, esi
1216     add   edi, (SIZEOF AMD_CONFIG_PARAMS + (3 * (SIZEOF EXECUTION_CACHE_REGION)))
1217     call  oemPlatformConfigInit
1218
1219     ; Call in to the AmdInitEarly entry point
1220     push  edx
1221     call  AmdBridge32
1222     pop   edx
1223
1224     ;;  EAX = AGESA_STATUS
1225     ;;  AGESA_SUCCESS The function has completed successfully.
1226     ;;  AGESA_ALERT An HyperTransportT link CRC error was observed.
1227     ;;  AGESA_WARNING One of more of the allocation rules were violated,
1228     ;;                but an adjustment was made and space was allocated.
1229     ;;                Or a HyperTransport device does not have the expected
1230     ;;                capabilities, or unusable redundant HyperTransport
1231     ;;                links were found.
1232     ;;  AGESA_ERROR One or more of the allocation rules were violated, which
1233     ;;              resulted in a requested cache region to not be allocated.
1234     ;;              Or, a HyperTransport device failed to initialize.
1235     ;;  AGESA_CRITICAL An illegal or unsupported mixture of processor types was
1236     ;;                 found, or the processors installed were found to have an
1237     ;;                 insufficient MP capability rating for this platform.
1238
1239     .if (eax != AGESA_SUCCESS)
1240         mov   al, (AMD_EARLY_PARAMS ptr [esi]).StdHeader.HeapStatus
1241         mov   ebx, AGESA_B2_ADDRESS
1242         call  AmdProcessAgesaErrors
1243     .endif
1244
1245     ; Allow AGESA to free the space used by AmdInitEarly
1246     pop   esi
1247     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_RELEASE_STRUCT
1248     call  AmdBridge32
1249
1250
1251     popad
1252     ret
1253 AmdInitEarlyWrapper ENDP
1254
1255
1256 ;+---------------------------------------------------------------------------
1257 ;
1258 ;   AmdInitPostWrapper
1259 ;
1260 ;   Entry:
1261 ;     On Entry to "AmdInitPost" AGESA will display AGESA_TESTPOINT - C6h
1262 ;     DS - 0000 with 4 gigabyte access
1263 ;     ES - 0000 with 4 gigabyte access
1264 ;
1265 ;   Exit:
1266 ;     On Exit from "AmdInitPost" AGESA will display AGESA_TESTPOINT - C7h
1267 ;     None
1268 ;
1269 ;   Modified:
1270 ;     None
1271 ;
1272 ;   Purpose:
1273 ;     The main system memory is located, initialized, and brought on-line.
1274 ;     The processor(s) are prepared for full operation and control by the
1275 ;     host environment. Action details differ for the BSP and AP processor
1276 ;     cores.
1277 ;     For the BSP, the following actions are performed:
1278 ;       Full memory initialization and configuration. BSP is the master for
1279 ;       this process and may delegate some tasks to APs.
1280 ;       AP collection of data for use later.
1281 ;       Transfer the HOBs including the artifact data out of the pre-memory
1282 ;       cache storage into a temporary holding buffer in the main memory.
1283 ;       Check the BIST status of the BSP
1284 ;       Shut down the APs.
1285 ;       Prepare for the host environment to begin main boot activity.
1286 ;       Disable the pre-memory stack.
1287 ;     For the APs, the following actions are performed:
1288 ;       Report core identity information.
1289 ;       Execute indicated memory initialization processes as directed.
1290 ;       Check the BIST status of the AP
1291 ;       Disable the pre-memory stack.
1292 ;       Prepare to halt, giving control to host environment.
1293 ;     The entire range of system memory is enabled for Write-Back cache.
1294 ;     The fixed MTRRs and the variable MTRRs[7:6] are not changed in order
1295 ;     to leave in place any flash ROM region currently set for Write-Protect
1296 ;     execution cache.
1297 ;
1298 ;   Dependencies:
1299 ;     This procedure is called after the host environment has determined that
1300 ;     a normal boot to operating system should be performed after any system
1301 ;     warm reset is completed and after the configuration done by AmdInitEarly
1302 ;     has completed.
1303 ;
1304 ;     This procedure requires a stack. The host environment must use one of the
1305 ;     provided service functions to establish the stack environment prior to
1306 ;     making the call to this procedure.
1307 ;
1308 ;     The processes performed at this time point require communication between
1309 ;     processor cores.  The host environment must recognize that all processor
1310 ;     cores are running in parallel and avoid activities that might interfere
1311 ;     with the core-to-core communication, such as modifying the MTRR settings
1312 ;     or writing to the APIC registers.
1313 ;
1314 AmdInitPostWrapper PROC NEAR PUBLIC
1315     local localCfgBlock:AMD_INTERFACE_PARAMS
1316
1317     pushad
1318
1319     ; Prepare for the call to create and initialize the input parameters for AmdInitPost
1320     xor   eax, eax
1321     mov   ax, ss
1322     shl   eax, 4
1323     lea   esi, localCfgBlock
1324     add   esi, eax
1325     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.ImageBasePtr, AGESA_B2_ADDRESS
1326     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_CREATE_STRUCT
1327     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.AltImageBasePtr, 0
1328     mov   edx, SEG AmdCallout16
1329     shl   edx, 4
1330     add   edx, OFFSET AmdCallout16
1331     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.CalloutPtr, edx
1332
1333     mov   (AMD_INTERFACE_PARAMS ptr [esi]).AgesaFunctionName, AMD_INIT_POST
1334     mov   (AMD_INTERFACE_PARAMS ptr [esi]).AllocationMethod, PreMemHeap
1335     mov   (AMD_INTERFACE_PARAMS ptr [esi]).NewStructSize, 0
1336     push  esi
1337     mov   dx, SEG AmdCalloutRouterPremem
1338     shl   edx, 16
1339     mov   dx, OFFSET AmdCalloutRouterPremem
1340     push  edx
1341     call  AmdBridge32
1342     pop   edx
1343
1344     mov   esi, (AMD_INTERFACE_PARAMS ptr [esi]).NewStructPtr
1345
1346     ; The structure has been initialized.  Now modify the default settings as desired.
1347
1348     mov   edi, esi
1349     add   edi, SIZEOF AMD_CONFIG_PARAMS
1350     call  oemPlatformConfigInit
1351
1352     ; Call in to the AmdInitPost entry point
1353     push  edx
1354     call  AmdBridge32
1355     pop   edx
1356
1357     ;;  EAX = AGESA_STATUS
1358     ;;  AGESA_SUCCESS The function has completed successfully.
1359     ;;  AGESA_ALERT   A BIST error was found on one of the cores.
1360     ;;  AGESA_WARNING HT Assist feature is running sub-optimally.
1361     ;;  AGESA_FATAL   Memory initialization failed.
1362
1363     .if (eax != AGESA_SUCCESS)
1364         mov   al, (AMD_POST_PARAMS ptr [esi]).StdHeader.HeapStatus
1365         mov   ebx, AGESA_B2_ADDRESS
1366         call  AmdProcessAgesaErrors
1367     .endif
1368
1369     ; Allow AGESA to free the space used by AmdInitPost
1370     pop   esi
1371     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_RELEASE_STRUCT
1372     call  AmdBridge32
1373
1374
1375     popad
1376     ret
1377 AmdInitPostWrapper ENDP
1378
1379
1380 ;+---------------------------------------------------------------------------
1381 ;
1382 ;   AmdInitResumeWrapper
1383 ;
1384 ;   Entry:
1385 ;     On Entry to "AmdInitResume" AGESA will display AGESA_TESTPOINT - D0h
1386 ;     DS - 0000 with 4 gigabyte access
1387 ;     ES - 0000 with 4 gigabyte access
1388 ;
1389 ;   Exit:
1390 ;     On Exit from "AmdInitResume" AGESA will display AGESA_TESTPOINT - D1h
1391 ;     None
1392 ;
1393 ;   Modified:
1394 ;     None
1395 ;
1396 ;   Purpose:
1397 ;     This procedure initializes or re-initializes the silicon components
1398 ;     for the resume boot path.  For the processor, main memory is brought
1399 ;     out of self-refresh mode. This procedure will use the context data
1400 ;     in the NvStorage area of the input structure to re-start the main
1401 ;     memory.  The host environment must fill the AMD_S3_PARAMS NvStorage
1402 ;     and VolatileStorage pointers and related size elements to describe
1403 ;     the location of the context data. Note that for this procedure, the
1404 ;     two data areas do not need to be contained in one buffer zone, they
1405 ;     can be anywhere in the accessible memory address space. If the host
1406 ;     environment uses a non-volatile storage device accessed on the system
1407 ;     address bus such as flashROM, then the context data does not need to
1408 ;     be moved prior to this call. If the host environment uses a non-
1409 ;     volatile storage device not located on the system address bus (e.g.
1410 ;     CMOS or SSEPROM) then the host environment must transfer the context
1411 ;     data to a buffer in main memory prior to calling this procedure.
1412 ;
1413 ;   Dependencies:
1414 ;     The host environment must have determined that the system should take
1415 ;     the resume path prior to calling this procedure. The configuration
1416 ;     done by AmdInitEarly and any necessary warm reset must be complete.
1417 ;     After this procedure, execution proceeds to general system restoration.
1418 ;
1419 ;     This procedure requires a stack. The host environment must use one of
1420 ;     the provided service functions to establish the stack environment prior
1421 ;     to making the call to this procedure.
1422 ;
1423 AmdInitResumeWrapper PROC NEAR PUBLIC
1424     local localCfgBlock:AMD_INTERFACE_PARAMS
1425
1426     pushad
1427
1428     ; Prepare for the call to create and initialize the input parameters for AmdInitResume
1429     xor   eax, eax
1430     mov   ax, ss
1431     shl   eax, 4
1432     lea   esi, localCfgBlock
1433     add   esi, eax
1434     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.ImageBasePtr, AGESA_B2_ADDRESS
1435     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_CREATE_STRUCT
1436     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.AltImageBasePtr, 0
1437     mov   edx, SEG AmdCallout16
1438     shl   edx, 4
1439     add   edx, OFFSET AmdCallout16
1440     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.CalloutPtr, edx
1441
1442     mov   (AMD_INTERFACE_PARAMS ptr [esi]).AgesaFunctionName, AMD_INIT_RESUME
1443     mov   (AMD_INTERFACE_PARAMS ptr [esi]).AllocationMethod, PreMemHeap
1444     mov   (AMD_INTERFACE_PARAMS ptr [esi]).NewStructSize, 0
1445     push  esi
1446     mov   dx, SEG AmdCalloutRouterPremem
1447     shl   edx, 16
1448     mov   dx, OFFSET AmdCalloutRouterPremem
1449     push  edx
1450     call  AmdBridge32
1451     pop   edx
1452
1453     mov   esi, (AMD_INTERFACE_PARAMS ptr [esi]).NewStructPtr
1454
1455     ; The structure has been initialized.  Now modify the default settings as desired.
1456
1457     mov   edi, esi
1458     add   edi, (SIZEOF AMD_CONFIG_PARAMS + SIZEOF AMD_S3_PARAMS)
1459     call  oemPlatformConfigInit
1460
1461     call  myGetNonVolatileS3Context
1462     mov   (AMD_RESUME_PARAMS ptr [esi]).S3DataBlock.NvStorage, ebx
1463     mov   (AMD_RESUME_PARAMS ptr [esi]).S3DataBlock.NvStorageSize, ecx
1464
1465     ; Call in to the AmdInitResume entry point
1466     push  edx
1467     call  AmdBridge32
1468     pop   edx
1469
1470     ;;  EAX = AGESA_STATUS
1471     ;;  AGESA_SUCCESS Re-initialization has been completed successfully.
1472     .if (eax != AGESA_SUCCESS)
1473         mov   al, (AMD_RESUME_PARAMS ptr [esi]).StdHeader.HeapStatus
1474         mov   ebx, AGESA_B2_ADDRESS
1475         call  AmdProcessAgesaErrors
1476     .endif
1477
1478
1479     ; Allow AGESA to free the space used by AmdInitResume
1480     pop   esi
1481     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_RELEASE_STRUCT
1482     call  AmdBridge32
1483
1484
1485     popad
1486     ret
1487 AmdInitResumeWrapper ENDP
1488
1489
1490 ;+---------------------------------------------------------------------------
1491 ;
1492 ;   AmdCalloutRouterPremem
1493 ;
1494 ;   Entry:
1495 ;     ECX - Callout function number
1496 ;     EDX - Function-specific UINTN
1497 ;     ESI - Pointer to function specific data
1498 ;
1499 ;   Exit:
1500 ;     EAX - Contains the AGESA_STATUS return code.
1501 ;
1502 ;   Modified:
1503 ;     None
1504 ;
1505 ;   Purpose:
1506 ;     The call out router function for AmdInitEarly,
1507 ;     AmdInitPost, and AmdInitResume.
1508 ;
1509 ;   Dependencies:
1510 ;     None
1511 ;
1512 AmdCalloutRouterPremem PROC FAR PUBLIC USES ECX EBX ESI BX DI DS ES
1513     xor   ax, ax
1514     mov   ds, ax
1515     mov   es, ax
1516     lea   di, cs:CalloutRouterTablePremem
1517     mov   eax, AGESA_UNSUPPORTED
1518
1519 loopThruTable:
1520     cmp   di, OFFSET cs:CalloutRouterTablePrememEnd
1521     jae   amdCpuCalloutExit ; exit with AGESA_UNSUPPORTED
1522     cmp   ecx, cs:[di].sOemCallout.FuncName
1523     je    FoundMatch
1524     add   di, SIZEOF sOemCallout
1525     jmp   loopThruTable
1526
1527 FoundMatch:
1528     mov   bx, cs:[di].sOemCallout.FuncPtr
1529     call  bx
1530
1531 amdCpuCalloutExit:
1532     ret
1533 AmdCalloutRouterPremem ENDP
1534
1535
1536 ;----------------------------------------------------------------------------
1537 ; Define the callout dispatch table for the prememory segment
1538 ;----------------------------------------------------------------------------
1539
1540 CalloutRouterTablePremem LABEL BYTE
1541     ;; Add entries as desired.
1542     sOemCallout <AGESA_READ_SPD, OFFSET myReadSPDPremem>
1543     sOemCallout <AGESA_HOOKBEFORE_DRAM_INIT, OFFSET myHookBeforeDramInit>
1544     sOemCallout <AGESA_HOOKBEFORE_DQS_TRAINING, OFFSET myHookBeforeDQSTraining>
1545     sOemCallout <AGESA_HOOKBEFORE_EXIT_SELF_REF, OFFSET myAgesaHookBeforeExitSelfRefresh>
1546     sOemCallout <AGESA_DO_RESET, OFFSET myDoReset>
1547     sOemCallout <AGESA_EXTERNAL____TRAIN_VREF_CHANGE, OFFSET my__TrainVrefChange>
1548 CalloutRouterTablePrememEnd LABEL BYTE
1549
1550
1551
1552 AMD_PREMEM_END
1553
1554
1555 ;----------------------------------------------------------------------------
1556 ;    POST SEGMENT
1557 ; This segment may be decompressed and run from system RAM.
1558 ;----------------------------------------------------------------------------
1559
1560 AMD_POST_START
1561
1562
1563 ;----------------------------------------------------------------------------
1564 ; Declare the external routines required in the POST segment
1565 ;----------------------------------------------------------------------------
1566
1567 ;+---------------------------------------------------------------------------
1568 ;
1569 ;   myAllocateBuffer (Required)
1570 ;
1571 ;   Entry:
1572 ;     Prior to this hook, AGESA will display - AGESA_TESTPOINT - E2h
1573 ;     ESI - Pointer to an AGESA_BUFFER_PARAMS structure.
1574 ;
1575 ;           typedef struct {
1576 ;             IN OUT   AMD_CONFIG_PARAMS StdHeader;
1577 ;             IN       UINT32 BufferLength;
1578 ;             IN       UINT32 BufferHandle;
1579 ;                OUT   VOID *BufferPointer;
1580 ;           } AGESA_BUFFER_PARAMS;
1581 ;
1582 ;   Exit:
1583 ;     After this hook, AGESA will display - AGESA_TESTPOINT - E3h
1584 ;     EAX - Contains the AGESA_STATUS return code.
1585 ;           AGESA_SUCCESS The requested size of memory has been
1586 ;                         successfully allocated.
1587 ;           AGESA_UNSUPPORTED This is a required function, so this
1588 ;                             value being returned causes a critical
1589 ;                             error response value from the AGESA
1590 ;                             software function.
1591 ;           AGESA_ERROR Less than the requested amount of memory
1592 ;                       was allocated.
1593 ;
1594 ;   Modified:
1595 ;     EAX
1596 ;
1597 ;   Purpose:
1598 ;     This function is used after main memory has been initialized
1599 ;     and the host environment has taken control of memory allocation.
1600 ;     This function must allocate a buffer of the requested size or
1601 ;     larger. This function is required to be implemented by the host
1602 ;     environment.
1603 ;
1604 ;   Dependencies:
1605 ;     The following call-outs must work together in the host system.
1606 ;     Parameters of the same name have the same function and must be
1607 ;     treated the same in each function:
1608 ;       AgesaAllocateBuffer
1609 ;       AgesaDeallocateBuffer
1610 ;       AgesaLocateBuffer
1611 ;       AgesaRunFcnOnAp
1612 ;     The host environment may need to reserve a location in the buffer
1613 ;     to store any host environment specific value(s). The returned
1614 ;     pointer must not include this reserved space. The host environment
1615 ;     on the AgesaDeallocateBuffer call needs to account for the reserved
1616 ;     space.  This reserved space may be an identifier or the "handle"
1617 ;     used to identify the specific memory block.
1618 ;
1619 EXTERN myAllocateBuffer:NEAR
1620
1621 ;+---------------------------------------------------------------------------
1622 ;
1623 ;   myDeallocateBuffer (Required)
1624 ;
1625 ;   Entry:
1626 ;     Prior to this hook, AGESA will display - AGESA_TESTPOINT - E4h
1627 ;     ESI - Pointer to an AGESA_BUFFER_PARAMS structure.
1628 ;
1629 ;           typedef struct {
1630 ;             IN OUT   AMD_CONFIG_PARAMS StdHeader;
1631 ;             IN       UINT32 BufferLength;
1632 ;             IN       UINT32 BufferHandle;
1633 ;                OUT   VOID *BufferPointer;
1634 ;           } AGESA_BUFFER_PARAMS;
1635 ;
1636 ;   Exit:
1637 ;     After this hook, AGESA will display - AGESA_TESTPOINT - E5h
1638 ;     EAX - Contains the AGESA_STATUS return code.
1639 ;           AGESA_SUCCESS The function has completed successfully.
1640 ;           AGESA_BOUNDS_CHK The BufferHandle is invalid. The AGESA
1641 ;                            software continues with its function.
1642 ;           AGESA_UNSUPPORTED This is a required function, so this
1643 ;                             value being returned causes a critical
1644 ;                             error response value from the AGESA
1645 ;                             software function.
1646 ;
1647 ;   Modified:
1648 ;     EAX
1649 ;
1650 ;   Purpose:
1651 ;     This function is used after main memory has been initialized
1652 ;     and the host environment has taken control of memory allocation.
1653 ;     This function releases a valid working buffer. This function is
1654 ;     required for the host environment to implement.
1655 ;
1656 ;   Dependencies:
1657 ;     The following call-outs must work together in the host system.
1658 ;     Parameters of the same name have the same function and must be
1659 ;     treated the same in each function:
1660 ;       AgesaAllocateBuffer
1661 ;       AgesaDeallocateBuffer
1662 ;       AgesaLocateBuffer
1663 ;       AgesaRunFcnOnAp
1664 ;
1665 EXTERN myDeallocateBuffer:NEAR
1666
1667 ;+---------------------------------------------------------------------------
1668 ;
1669 ;   myLocateBuffer (Required)
1670 ;
1671 ;   Entry:
1672 ;     Prior to this hook, AGESA will display - AGESA_TESTPOINT - E6h
1673 ;     ESI - Pointer to an AGESA_BUFFER_PARAMS structure.
1674 ;
1675 ;           typedef struct {
1676 ;             IN OUT   AMD_CONFIG_PARAMS StdHeader;
1677 ;             IN       UINT32 BufferLength;
1678 ;             IN       UINT32 BufferHandle;
1679 ;                OUT   VOID *BufferPointer;
1680 ;           } AGESA_BUFFER_PARAMS;
1681 ;
1682 ;   Exit:
1683 ;     After this hook, AGESA will display - AGESA_TESTPOINT - E7h
1684 ;     EAX - Contains the AGESA_STATUS return code.
1685 ;           AGESA_SUCCESS The function has completed successfully.
1686 ;           AGESA_BOUNDS_CHK The presented handle is invalid or the
1687 ;                            buffer could not be located.
1688 ;
1689 ;   Modified:
1690 ;     EAX
1691 ;
1692 ;   Purpose:
1693 ;     This function is used after main memory has been initialized
1694 ;     and the host environment has taken control of memory allocation.
1695 ;     This function must locate the buffer related to the indicated
1696 ;     handle and return the address of the buffer and its length.
1697 ;     This function is required to be implemented in the host
1698 ;     environment.
1699 ;
1700 ;   Dependencies:
1701 ;     The following call-outs must work together in the host system.
1702 ;     Parameters of the same name have the same function and must be
1703 ;     treated the same in each function:
1704 ;       AgesaAllocateBuffer
1705 ;       AgesaDeallocateBuffer
1706 ;       AgesaLocateBuffer
1707 ;       AgesaRunFcnOnAp
1708 ;
1709 EXTERN myLocateBuffer:NEAR
1710
1711
1712 ;+---------------------------------------------------------------------------
1713 ;
1714 ;   myRunFuncOnAp (Required)
1715 ;
1716 ;   Entry:
1717 ;     EDX - Local APIC ID of the target core.
1718 ;
1719 ;   Exit:
1720 ;     None
1721 ;
1722 ;   Modified:
1723 ;     None
1724 ;
1725 ;   Purpose:
1726 ;     The host environment must route execution to the target AP and
1727 ;     have that AP call the AmdLateRunApTaskWrapper routine defined
1728 ;     above.
1729 ;
1730 ;   Dependencies:
1731 ;     None
1732 ;
1733 EXTERN myRunFuncOnAp:NEAR
1734
1735 ;+---------------------------------------------------------------------------
1736 ;
1737 ;   mySaveNonVolatileS3Context (Required for proper S3 operation)
1738 ;
1739 ;   Entry:
1740 ;     EBX - Pointer to the non-volatile S3 context block
1741 ;     ECX - Size in bytes of the non-volatile S3 context block
1742 ;
1743 ;   Exit:
1744 ;     None
1745 ;
1746 ;   Modified:
1747 ;     None
1748 ;
1749 ;   Purpose:
1750 ;     The host environment must save the non-volatile data to an area
1751 ;     that will not lose context while in the ACPI S3 sleep state, but
1752 ;     cannot be placed in system RAM.  This data will need to be
1753 ;     available during the call to AmdInitResume.
1754 ;
1755 ;   Dependencies:
1756 ;     None
1757 ;
1758 EXTERN mySaveNonVolatileS3Context:NEAR
1759
1760 ;+---------------------------------------------------------------------------
1761 ;
1762 ;   mySaveVolatileS3Context (Required for proper S3 operation)
1763 ;
1764 ;   Entry:
1765 ;     EBX - Pointer to the volatile S3 context block
1766 ;     ECX - Size in bytes of the volatile S3 context block
1767 ;
1768 ;   Exit:
1769 ;     None
1770 ;
1771 ;   Modified:
1772 ;     None
1773 ;
1774 ;   Purpose:
1775 ;     The host environment must save the volatile data to an area
1776 ;     that will not lose context while in the ACPI S3 sleep state.
1777 ;     This data will need to be available during the call to
1778 ;     AmdS3LateRestore.
1779 ;
1780 ;   Dependencies:
1781 ;     None
1782 ;
1783 EXTERN mySaveVolatileS3Context:NEAR
1784
1785 ;+---------------------------------------------------------------------------
1786 ;
1787 ;   myGetVolatileS3Context (Required for proper S3 operation)
1788 ;
1789 ;   Entry:
1790 ;     None
1791 ;
1792 ;   Exit:
1793 ;     EBX - Pointer to the volatile S3 context block
1794 ;     ECX - Size in bytes of the volatile S3 context block
1795 ;
1796 ;   Modified:
1797 ;     None
1798 ;
1799 ;   Purpose:
1800 ;     The host environment must return the pointer to the data
1801 ;     saved during the mySaveVolatileS3Context routine.
1802 ;
1803 ;   Dependencies:
1804 ;     None
1805 ;
1806 EXTERN myGetVolatileS3Context:NEAR
1807
1808
1809 ;----------------------------------------------------------------------------
1810 ; Define the sample wrapper routines for the POST segment
1811 ;----------------------------------------------------------------------------
1812
1813 ;+---------------------------------------------------------------------------
1814 ;
1815 ;   AmdInitEnvWrapper
1816 ;
1817 ;   Entry:
1818 ;     On Entry to "AmdInitEnv" AGESA will display AGESA_TESTPOINT - C8h
1819 ;     DS - 0000 with 4 gigabyte access
1820 ;     ES - 0000 with 4 gigabyte access
1821 ;
1822 ;   Exit:
1823 ;     On Exit from "AmdInitEnv" AGESA will display AGESA_TESTPOINT - C9h
1824 ;     None
1825 ;
1826 ;   Modified:
1827 ;     None
1828 ;
1829 ;   Purpose:
1830 ;     This procedure uses the AgesaAllocateBuffer call-out to acquire
1831 ;     permanent buffer space for the UEFI Hand-Off Blocks (HOBs). This
1832 ;     is also known as, or includes, artifact data being used by the
1833 ;     AGESA software. Upon entry to this procedure, the data is being
1834 ;     held in a temporary memory location and it must be moved to a
1835 ;     location controlled and protected by the host environment.
1836 ;
1837 ;     These actions are performed by the BSP. The APs are not assigned
1838 ;     any tasks at this time point.
1839 ;
1840 ;   Dependencies:
1841 ;     This procedure must be called after full memory is initialized and
1842 ;     the host environment has taken control of main memory allocation.
1843 ;     This procedure should be called before the PCI enumeration takes
1844 ;     place and as soon as possible after the host environment memory
1845 ;     allocation sub-system has started.
1846 ;
1847 ;     This procedure requires a stack. The host environment must use one
1848 ;     of the provided service functions to establish the stack environment
1849 ;     prior to making the call to this procedure.
1850 ;
1851 AmdInitEnvWrapper PROC NEAR PUBLIC
1852     local localCfgBlock:AMD_INTERFACE_PARAMS
1853
1854     pushad
1855
1856     ; Prepare for the call to create and initialize the input parameters for AmdInitEnv
1857     xor   eax, eax
1858     mov   ax, ss
1859     shl   eax, 4
1860     lea   esi, localCfgBlock
1861     add   esi, eax
1862     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.ImageBasePtr, AGESA_B2_ADDRESS
1863     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_CREATE_STRUCT
1864     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.AltImageBasePtr, 0
1865     mov   edx, SEG AmdCallout16
1866     shl   edx, 4
1867     add   edx, OFFSET AmdCallout16
1868     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.CalloutPtr, edx
1869
1870     mov   (AMD_INTERFACE_PARAMS ptr [esi]).AgesaFunctionName, AMD_INIT_ENV
1871     mov   (AMD_INTERFACE_PARAMS ptr [esi]).AllocationMethod, PostMemDram
1872     mov   (AMD_INTERFACE_PARAMS ptr [esi]).NewStructSize, 0
1873     push  esi
1874     mov   dx, SEG AmdCalloutRouterPost
1875     shl   edx, 16
1876     mov   dx, OFFSET AmdCalloutRouterPost
1877     push  edx
1878     call  AmdBridge32
1879     pop   edx
1880
1881     mov   esi, (AMD_INTERFACE_PARAMS ptr [esi]).NewStructPtr
1882
1883     ; The structure has been initialized.  Now modify the default settings as desired.
1884
1885     mov   edi, esi
1886     add   edi, SIZEOF AMD_CONFIG_PARAMS
1887     call  oemPlatformConfigInit
1888
1889     ; Call in to the AmdInitEnv entry point
1890     push  edx
1891     call  AmdBridge32
1892     pop   edx
1893
1894     ;;  EAX = AGESA_STATUS
1895     ;;  AGESA_SUCCESS The function has completed successfully.
1896     ;;  AGESA_ERROR The artifact data could not be found or the host
1897     ;;  environment failed to allocate sufficient buffer space.
1898
1899     .if (eax != AGESA_SUCCESS)
1900         mov   al, (AMD_ENV_PARAMS ptr [esi]).StdHeader.HeapStatus
1901         mov   ebx, AGESA_B2_ADDRESS
1902         call  AmdProcessAgesaErrors
1903     .endif
1904
1905     ; Allow AGESA to free the space used by AmdInitEnv
1906     pop   esi
1907     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_RELEASE_STRUCT
1908     call  AmdBridge32
1909
1910
1911     popad
1912     ret
1913 AmdInitEnvWrapper ENDP
1914
1915
1916 ;+---------------------------------------------------------------------------
1917 ;
1918 ;   AmdInitMidWrapper
1919 ;
1920 ;   Entry:
1921 ;     On Entry to "AmdInitMid" AGESA will display AGESA_TESTPOINT - CAh
1922 ;     DS - 0000 with 4 gigabyte access
1923 ;     ES - 0000 with 4 gigabyte access
1924 ;
1925 ;   Exit:
1926 ;     On Exit from "AmdInitMid" AGESA will display AGESA_TESTPOINT - CBh
1927 ;     None
1928 ;
1929 ;   Modified:
1930 ;     None
1931 ;
1932 ;   Purpose:
1933 ;     This procedure call performs special configuration requirements for
1934 ;     the graphics display hardware.
1935 ;
1936 ;     These actions are performed by the BSP. The APs are not assigned any
1937 ;     tasks at this time point.
1938 ;
1939 ;   Dependencies:
1940 ;     This procedure must be called after PCI enumeration has allocated
1941 ;     resources, but before the video BIOS call is performed.
1942 ;
1943 ;     This procedure requires a stack. The host environment must use one
1944 ;     of the provided service functions to establish the stack environment
1945 ;     prior to making the call to this procedure.
1946 ;
1947 AmdInitMidWrapper PROC NEAR PUBLIC
1948     local localCfgBlock:AMD_INTERFACE_PARAMS
1949
1950     pushad
1951
1952     ; Prepare for the call to create and initialize the input parameters for AmdInitMid
1953     xor   eax, eax
1954     mov   ax, ss
1955     shl   eax, 4
1956     lea   esi, localCfgBlock
1957     add   esi, eax
1958     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.ImageBasePtr, AGESA_B2_ADDRESS
1959     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_CREATE_STRUCT
1960     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.AltImageBasePtr, 0
1961     mov   edx, SEG AmdCallout16
1962     shl   edx, 4
1963     add   edx, OFFSET AmdCallout16
1964     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.CalloutPtr, edx
1965
1966     mov   (AMD_INTERFACE_PARAMS ptr [esi]).AgesaFunctionName, AMD_INIT_MID
1967     mov   (AMD_INTERFACE_PARAMS ptr [esi]).AllocationMethod, PostMemDram
1968     mov   (AMD_INTERFACE_PARAMS ptr [esi]).NewStructSize, 0
1969     push  esi
1970     mov   dx, SEG AmdCalloutRouterPost
1971     shl   edx, 16
1972     mov   dx, OFFSET AmdCalloutRouterPost
1973     push  edx
1974     call  AmdBridge32
1975     pop   edx
1976
1977     mov   esi, (AMD_INTERFACE_PARAMS ptr [esi]).NewStructPtr
1978
1979     ; The structure has been initialized.  Now modify the default settings as desired.
1980
1981     mov   edi, esi
1982     add   edi, SIZEOF AMD_CONFIG_PARAMS
1983     call  oemPlatformConfigInit
1984
1985     ; Call in to the AmdInitMid entry point
1986     push  edx
1987     call  AmdBridge32
1988     pop   edx
1989
1990     ;;  EAX = AGESA_STATUS
1991     ;;  AGESA_SUCCESS The function has completed successfully.
1992
1993     .if (eax != AGESA_SUCCESS)
1994         mov   al, (AMD_MID_PARAMS ptr [esi]).StdHeader.HeapStatus
1995         mov   ebx, AGESA_B2_ADDRESS
1996         call  AmdProcessAgesaErrors
1997     .endif
1998
1999     ; Allow AGESA to free the space used by AmdInitMid
2000     pop   esi
2001     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_RELEASE_STRUCT
2002     call  AmdBridge32
2003
2004
2005     popad
2006     ret
2007
2008 AmdInitMidWrapper ENDP
2009
2010
2011 ;+---------------------------------------------------------------------------
2012 ;
2013 ;   AmdInitLateWrapper
2014 ;
2015 ;   Entry:
2016 ;     On Entry to "AmdInitLate" AGESA will display AGESA_TESTPOINT - CCh
2017 ;     DS - 0000 with 4 gigabyte access
2018 ;     ES - 0000 with 4 gigabyte access
2019 ;
2020 ;   Exit:
2021 ;     On Exit from "AmdInitLate" AGESA will display AGESA_TESTPOINT - CDh
2022 ;     None
2023 ;
2024 ;   Modified:
2025 ;     None
2026 ;
2027 ;   Purpose:
2028 ;     The main purpose of this function is to generate informational
2029 ;     data tables used by the operating system. The individual tables
2030 ;     can be selected for generation through the user selection entries
2031 ;     on the input parameters.
2032 ;
2033 ;     This routine uses the Call-Out AgesaAllocateBuffer to allocate a
2034 ;     buffer of the proper size to contain the data.
2035 ;
2036 ;     The code path separates the BSP from the APs and perform a separate
2037 ;     and appropriate list of tasks for each class of core.
2038 ;     For the BSP, the following actions are performed:
2039 ;       Allocate buffer space for the tables.
2040 ;       Generate the table contents.
2041 ;       Make sure that the CPU is in a known good power state before
2042 ;       proceeding to boot the OS.
2043 ;     For the APs, the following actions are performed:
2044 ;       Final register settings preparing for entry to OS.
2045 ;       Establish the final PState for entry to OS.
2046 ;
2047 ;   Dependencies:
2048 ;     This routine is expected to be executed late in the boot sequence
2049 ;     after main memory has been initialized, after PCI enumeration has
2050 ;     completed, after the host environment ACPI sub-system has started,
2051 ;     after the host environment has taken control of the APs, but just
2052 ;     before the start of OS boot.
2053 ;
2054 ;     The host environment must provide the required call-outs listed in
2055 ;     the "Required Call-Out Procedures" section of the AGESA interface
2056 ;     specification to provide the buffer space in main memory and execute
2057 ;     code on the APs. The host environment must register the created ACPI
2058 ;     table in the main ACPI pointer tables. This may require moving the
2059 ;     generated tables to another location in memory.
2060 ;
2061 ;     This procedure requires a stack. The host environment must establish
2062 ;     the stack environment prior to making the call to this procedure.
2063 ;     Some functions depend upon the preservation of the heap data across
2064 ;     the shift from pre-memory environment to a post-memory environment.
2065 ;     If that data was not preserved, then those functions cannot complete
2066 ;     and an error is returned.
2067 ;
2068 AmdInitLateWrapper PROC NEAR PUBLIC
2069     local localCfgBlock:AMD_INTERFACE_PARAMS
2070
2071     pushad
2072
2073     ; Prepare for the call to create and initialize the input parameters for AmdInitLate
2074     xor   eax, eax
2075     mov   ax, ss
2076     shl   eax, 4
2077     lea   esi, localCfgBlock
2078     add   esi, eax
2079     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.ImageBasePtr, AGESA_B2_ADDRESS
2080     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_CREATE_STRUCT
2081     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.AltImageBasePtr, 0
2082     mov   edx, SEG AmdCallout16
2083     shl   edx, 4
2084     add   edx, OFFSET AmdCallout16
2085     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.CalloutPtr, edx
2086
2087     mov   (AMD_INTERFACE_PARAMS ptr [esi]).AgesaFunctionName, AMD_INIT_LATE
2088     mov   (AMD_INTERFACE_PARAMS ptr [esi]).AllocationMethod, PostMemDram
2089     mov   (AMD_INTERFACE_PARAMS ptr [esi]).NewStructSize, 0
2090     push  esi
2091     mov   dx, SEG AmdCalloutRouterPost
2092     shl   edx, 16
2093     mov   dx, OFFSET AmdCalloutRouterPost
2094     push  edx
2095     call  AmdBridge32
2096     pop   edx
2097
2098     mov   esi, (AMD_INTERFACE_PARAMS ptr [esi]).NewStructPtr
2099
2100     ; The structure has been initialized.  Now modify the default settings as desired.
2101
2102     mov   edi, esi
2103     add   edi, SIZEOF AMD_CONFIG_PARAMS
2104     call  oemPlatformConfigInit
2105
2106     ; Call in to the AmdInitLate entry point
2107     push  edx
2108     call  AmdBridge32
2109     pop   edx
2110
2111     ;;  EAX = AGESA_STATUS
2112     ;;  AGESA_SUCCESS The function has completed successfully.
2113     ;;  AGESA_ALERT
2114     ;;  AGESA_ERROR The system could not allocate the needed amount of
2115     ;;  buffer space; or could not locate the artifact data block in
2116     ;;  memory. Likely cause: the host environment may not have preserved
2117     ;;  the data properly.
2118
2119     .if (eax != AGESA_SUCCESS)
2120         mov   al, (AMD_LATE_PARAMS ptr [esi]).StdHeader.HeapStatus
2121         mov   ebx, AGESA_B2_ADDRESS
2122         call  AmdProcessAgesaErrors
2123     .endif
2124
2125     push  es
2126     mov   ax, SEG AmdAcpiSratPointer
2127     mov   es, ax
2128
2129     mov   ebx, (AMD_LATE_PARAMS ptr [esi]).AcpiSrat
2130     mov   es:AmdAcpiSratPointer, ebx
2131     mov   eax, DWORD PTR [ebx + 4]
2132     mov   es:AmdAcpiSratSize, eax
2133
2134     mov   ebx, (AMD_LATE_PARAMS ptr [esi]).AcpiSlit
2135     mov   es:AmdAcpiSlitPointer, ebx
2136     mov   eax, DWORD PTR [ebx + 4]
2137     mov   es:AmdAcpiSlitSize, eax
2138
2139     mov   ebx, (AMD_LATE_PARAMS ptr [esi]).AcpiPState
2140     mov   es:AmdAcpiSsdtPointer, ebx
2141     mov   eax, DWORD PTR [ebx + 4]
2142     mov   es:AmdAcpiSsdtSize, eax
2143
2144     xor   eax, eax
2145
2146     mov   ebx, (AMD_LATE_PARAMS ptr [esi]).AcpiWheaMce
2147     mov   es:AmdAcpiWheaMcePointer, ebx
2148     mov   ax, WORD PTR [ebx]
2149     mov   es:AmdAcpiWheaMceSize, eax
2150
2151     mov   ebx, (AMD_LATE_PARAMS ptr [esi]).AcpiWheaMce
2152     mov   es:AmdAcpiWheaCmcPointer, ebx
2153     mov   ax, WORD PTR [ebx]
2154     mov   es:AmdAcpiWheaCmcSize, eax
2155
2156     mov   eax, (AMD_LATE_PARAMS ptr [esi]).DmiTable
2157     mov   es:AmdDmiInfoPointer, eax
2158     pop   es
2159
2160
2161     ; Allow AGESA to free the space used by AmdInitLate
2162     pop   esi
2163     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_RELEASE_STRUCT
2164     call  AmdBridge32
2165
2166     popad
2167     ret
2168
2169 AmdInitLateWrapper ENDP
2170
2171
2172 ;+---------------------------------------------------------------------------
2173 ;
2174 ;   AmdS3SaveWrapper
2175 ;
2176 ;   Entry:
2177 ;     On Entry to "AmdS3Save" AGESA will display AGESA_TESTPOINT - CEh
2178 ;     DS - 0000 with 4 gigabyte access
2179 ;     ES - 0000 with 4 gigabyte access
2180 ;
2181 ;   Exit:
2182 ;     On Entry to "AmdS3Save" AGESA will display AGESA_TESTPOINT - CFh
2183 ;     None
2184 ;
2185 ;   Modified:
2186 ;     None
2187 ;
2188 ;   Purpose:
2189 ;     This procedure saves critical registers and/or configuration
2190 ;     information for preservation across a system suspend mode. All
2191 ;     actions needed to prepare the processor for suspend mode is
2192 ;     performed, however this procedure does NOT initiate the suspend
2193 ;     process. The host environment is expected to perform that duty.
2194 ;
2195 ;     These actions are performed by the BSP. The APs are not assigned
2196 ;     any tasks at this time point.
2197 ;
2198 ;     The initializer routine will NULL out the save area pointers and
2199 ;     sizes. This procedure will determine the size of storage needed
2200 ;     for all the processor context, and make a call out to the environment
2201 ;     for allocation of one buffer to store all of the data. Upon exit, the
2202 ;     pointers and sizes within the AMD_S3_PARAMS structure will be updated
2203 ;     with the appropriate addresses within the buffer that was allocated.
2204 ;     The host environment is expected to then transfer the data pointed to
2205 ;     by NvStorage to a non-volatile storage area, and the data pointed to
2206 ;     by VolatileStorage to either a non-volatile storage area or system
2207 ;     RAM that retains its content across suspend.
2208 ;
2209 ;   Dependencies:
2210 ;     The host environment must initiate the suspend process.
2211 ;
2212 ;     This procedure requires a stack. The host environment must establish
2213 ;     the stack environment prior to making the call to this procedure.
2214 ;
2215 AmdS3SaveWrapper PROC NEAR PUBLIC
2216     local localCfgBlock:AMD_INTERFACE_PARAMS
2217
2218     pushad
2219
2220     ; Prepare for the call to create and initialize the input parameters for AmdS3Save
2221     xor   eax, eax
2222     mov   ax, ss
2223     shl   eax, 4
2224     lea   esi, localCfgBlock
2225     add   esi, eax
2226     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.ImageBasePtr, AGESA_B2_ADDRESS
2227     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_CREATE_STRUCT
2228     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.AltImageBasePtr, 0
2229     mov   edx, SEG AmdCallout16
2230     shl   edx, 4
2231     add   edx, OFFSET AmdCallout16
2232     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.CalloutPtr, edx
2233
2234     mov   (AMD_INTERFACE_PARAMS ptr [esi]).AgesaFunctionName, AMD_S3_SAVE
2235     mov   (AMD_INTERFACE_PARAMS ptr [esi]).AllocationMethod, PostMemDram
2236     mov   (AMD_INTERFACE_PARAMS ptr [esi]).NewStructSize, 0
2237     push  esi
2238     mov   dx, SEG AmdCalloutRouterPost
2239     shl   edx, 16
2240     mov   dx, OFFSET AmdCalloutRouterPost
2241     push  edx
2242     call  AmdBridge32
2243     pop   edx
2244
2245     mov   esi, (AMD_INTERFACE_PARAMS ptr [esi]).NewStructPtr
2246
2247     ; The structure has been initialized.  Now modify the default settings as desired.
2248
2249     mov   edi, esi
2250     add   edi, (SIZEOF AMD_CONFIG_PARAMS + SIZEOF AMD_S3_PARAMS)
2251     call  oemPlatformConfigInit
2252
2253     ; Call in to the AmdS3Save entry point
2254     push  edx
2255     call  AmdBridge32
2256     pop   edx
2257
2258     ;;  EAX = AGESA_STATUS
2259     ;;  AGESA_SUCCESS All suspend duties have been completed successfully.
2260
2261     .if (eax != AGESA_SUCCESS)
2262         mov   al, (AMD_S3SAVE_PARAMS ptr [esi]).StdHeader.HeapStatus
2263         mov   ebx, AGESA_B2_ADDRESS
2264         call  AmdProcessAgesaErrors
2265     .endif
2266
2267     mov   ecx, (AMD_S3SAVE_PARAMS ptr [esi]).S3DataBlock.NvStorageSize
2268     .if (ecx != 0)
2269         mov   ebx, (AMD_S3SAVE_PARAMS ptr [esi]).S3DataBlock.NvStorage
2270         call  mySaveNonVolatileS3Context
2271     .endif
2272
2273     mov   ecx, (AMD_S3SAVE_PARAMS ptr [esi]).S3DataBlock.VolatileStorageSize
2274     .if (ecx != 0)
2275         mov   ebx, (AMD_S3SAVE_PARAMS ptr [esi]).S3DataBlock.VolatileStorage
2276         call  mySaveVolatileS3Context
2277     .endif
2278
2279     ; Allow AGESA to free the space used by AmdS3Save
2280     pop   esi
2281     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_RELEASE_STRUCT
2282     call  AmdBridge32
2283
2284     popad
2285     ret
2286
2287 AmdS3SaveWrapper ENDP
2288
2289
2290 ;+---------------------------------------------------------------------------
2291 ;
2292 ;   AmdS3LateRestoreWrapper
2293 ;
2294 ;   Entry:
2295 ;     On Entry to "AmdS3LateRestore" AGESA will display AGESA_TESTPOINT - D2h
2296 ;     DS - 0000 with 4 gigabyte access
2297 ;     ES - 0000 with 4 gigabyte access
2298 ;
2299 ;   Exit:
2300 ;     On Exit from "AmdS3LateRestore" AGESA will display AGESA_TESTPOINT - D3h
2301 ;     None
2302 ;
2303 ;   Modified:
2304 ;     None
2305 ;
2306 ;   Purpose:
2307 ;     This procedure restores the processor state, reloads critical
2308 ;     silicon component registers, and performs any re-initialization
2309 ;     required by the silicon. This procedure will use the context data
2310 ;     in the VolatileStorage area of the input structure to restore the
2311 ;     processor registers.
2312 ;
2313 ;     The host environment must fill the AMD_S3_PARAMS NvStorage and
2314 ;     VolatileStorage pointers and related size elements to describe
2315 ;     the location of the context data. Note that for this procedure,
2316 ;     the two data areas do not need to be contained in one buffer zone,
2317 ;     they can be anywhere in the accessible memory address space. If
2318 ;     the host environment uses a non-volatile storage device accessed
2319 ;     on the system address bus such as flashROM, then the context data
2320 ;     does not need to be moved prior to this call. If the host
2321 ;     environment uses a non-volatile storage device not located on the
2322 ;     system address bus (e.g. CMOS or SSEPROM) then the host environment
2323 ;     must transfer the context data to a buffer in main memory prior to
2324 ;     calling this procedure.
2325 ;
2326 ;     These actions are performed by the BSP. The APs are not assigned
2327 ;     any tasks at this time point.
2328 ;
2329 ;   Dependencies:
2330 ;     This procedure is called late in the resume sequence, after the
2331 ;     PCI control space is restored and just before resuming operating
2332 ;     system execution.
2333 ;
2334 ;     The host environment must initiate the OS restart process.
2335 ;
2336 ;     This procedure requires a stack. The host environment must establish
2337 ;     the stack environment prior to making the call to this procedure.
2338 ;
2339 AmdS3LateRestoreWrapper PROC NEAR PUBLIC
2340     local localCfgBlock:AMD_INTERFACE_PARAMS
2341
2342     pushad
2343
2344     ; Prepare for the call to create and initialize the input parameters for AmdS3LateRestore
2345     xor   eax, eax
2346     mov   ax, ss
2347     shl   eax, 4
2348     lea   esi, localCfgBlock
2349     add   esi, eax
2350     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.ImageBasePtr, AGESA_B2_ADDRESS
2351     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_CREATE_STRUCT
2352     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.AltImageBasePtr, 0
2353     mov   edx, SEG AmdCallout16
2354     shl   edx, 4
2355     add   edx, OFFSET AmdCallout16
2356     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.CalloutPtr, edx
2357
2358     mov   (AMD_INTERFACE_PARAMS ptr [esi]).AgesaFunctionName, AMD_S3LATE_RESTORE
2359     mov   (AMD_INTERFACE_PARAMS ptr [esi]).AllocationMethod, PostMemDram
2360     mov   (AMD_INTERFACE_PARAMS ptr [esi]).NewStructSize, 0
2361     push  esi
2362     mov   dx, SEG AmdCalloutRouterPost
2363     shl   edx, 16
2364     mov   dx, OFFSET AmdCalloutRouterPost
2365     push  edx
2366     call  AmdBridge32
2367     pop   edx
2368
2369     mov   esi, (AMD_INTERFACE_PARAMS ptr [esi]).NewStructPtr
2370
2371     ; The structure has been initialized.  Now modify the default settings as desired.
2372
2373     mov   edi, esi
2374     add   edi, (SIZEOF AMD_CONFIG_PARAMS + SIZEOF AMD_S3_PARAMS)
2375     call  oemPlatformConfigInit
2376
2377     call  myGetVolatileS3Context
2378     mov   (AMD_S3LATE_PARAMS ptr [esi]).S3DataBlock.VolatileStorage, ebx
2379     mov   (AMD_S3LATE_PARAMS ptr [esi]).S3DataBlock.VolatileStorageSize, ecx
2380
2381     ; Call in to the AmdS3LateRestore entry point
2382     push  edx
2383     call  AmdBridge32
2384     pop   edx
2385
2386     ;;  EAX = AGESA_STATUS
2387     ;;  AGESA_SUCCESS All resume processes have been completed successfully.
2388
2389     .if (eax != AGESA_SUCCESS)
2390         mov   al, (AMD_S3LATE_PARAMS ptr [esi]).StdHeader.HeapStatus
2391         mov   ebx, AGESA_B2_ADDRESS
2392         call  AmdProcessAgesaErrors
2393     .endif
2394
2395     ; Allow AGESA to free the space used by AmdS3LateRestore
2396     pop   esi
2397     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_RELEASE_STRUCT
2398     call  AmdBridge32
2399
2400     popad
2401     ret
2402 AmdS3LateRestoreWrapper ENDP
2403
2404
2405 ;+---------------------------------------------------------------------------
2406 ;
2407 ;   AmdLateRunApTaskWrapper
2408 ;
2409 ;   Entry:
2410 ;     Prior to this hook, AGESA will display - AGESA_TESTPOINT - D4h
2411 ;     DS - 0000 with 4 gigabyte access
2412 ;     ES - 0000 with 4 gigabyte access
2413 ;
2414 ;   Exit:
2415 ;     After this hook, AGESA will display - AGESA_TESTPOINT - D5h
2416 ;     None
2417 ;
2418 ;   Modified:
2419 ;     None
2420 ;
2421 ;   Purpose:
2422 ;     This entry point is tightly connected with the "AgesaRunFcnOnAp"
2423 ;     call out.  The AGESA software will call the call-out "AgesaRunFcnOnAp";
2424 ;     the host environment will then call this entry point to have the AP
2425 ;     execute the requested function. This is needed late in the Post and
2426 ;     Resume branches for running an AP task since the AGESA software has
2427 ;     relinquished control of the APs to the host environment.
2428 ;
2429 ;   Dependencies:
2430 ;     The host environment must implement the"AgesaRunFcnOnAp" call-out
2431 ;     and route execution to the target AP.
2432 ;
2433 AmdLateRunApTaskWrapper PROC NEAR PUBLIC
2434     local localCfgBlock:AMD_INTERFACE_PARAMS
2435
2436     pushad
2437
2438     ; Prepare for the call to create and initialize the input parameters for AmdLateRunApTask
2439     xor   eax, eax
2440     mov   ax, ss
2441     shl   eax, 4
2442     lea   esi, localCfgBlock
2443     add   esi, eax
2444     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.ImageBasePtr, AGESA_B2_ADDRESS
2445     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_CREATE_STRUCT
2446     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.AltImageBasePtr, 0
2447     mov   edx, SEG AmdCallout16
2448     shl   edx, 4
2449     add   edx, OFFSET AmdCallout16
2450     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.CalloutPtr, edx
2451
2452     mov   (AMD_INTERFACE_PARAMS ptr [esi]).AgesaFunctionName, AMD_LATE_RUN_AP_TASK
2453     mov   (AMD_INTERFACE_PARAMS ptr [esi]).AllocationMethod, PostMemDram
2454     mov   (AMD_INTERFACE_PARAMS ptr [esi]).NewStructSize, 0
2455     push  esi
2456     mov   dx, SEG AmdCalloutRouterPost
2457     shl   edx, 16
2458     mov   dx, OFFSET AmdCalloutRouterPost
2459     push  edx
2460     call  AmdBridge32
2461     pop   edx
2462
2463     mov   esi, (AMD_INTERFACE_PARAMS ptr [esi]).NewStructPtr
2464
2465     ; The structure has been initialized.  Now modify the default settings as desired.
2466
2467     push  es
2468     mov   ax, SEG AmdRunCodeOnApDataPointer
2469     mov   es, ax
2470     mov   eax, es:AmdRunCodeOnApDataPointer
2471     mov   (AP_EXE_PARAMS PTR [esi]).RelatedDataBlock, eax
2472     mov   eax, es:AmdRunCodeOnApDataSize
2473     mov   (AP_EXE_PARAMS PTR [esi]).RelatedBlockLength, eax
2474     mov   eax, es:AmdRunCodeOnApFunction
2475     mov   (AP_EXE_PARAMS PTR [esi]).FunctionNumber, eax
2476     pop   es
2477
2478     ; Call in to the AmdLateRunApTask dispatcher
2479     push  edx
2480     call  AmdBridge32
2481     pop   edx
2482
2483     ;;  EAX = AGESA_STATUS
2484     push  es
2485     mov   bx, SEG AmdRunCodeOnApStatus
2486     mov   es, bx
2487     mov   es:AmdRunCodeOnApStatus, eax
2488     pop   es
2489
2490     ; Allow AGESA to free the space used by AmdLateRunApTask
2491     pop   esi
2492     mov   (AMD_INTERFACE_PARAMS ptr [esi]).StdHeader.Func, AMD_RELEASE_STRUCT
2493     call  AmdBridge32
2494
2495     popad
2496     ret
2497
2498 AmdLateRunApTaskWrapper ENDP
2499
2500
2501 ;+---------------------------------------------------------------------------
2502 ;
2503 ;   AmdRunFuncOnAp (Required)
2504 ;
2505 ;   Entry:
2506 ;     Prior to this hook, AGESA will display - AGESA_TESTPOINT - E8h
2507 ;     EDX - Local APIC ID of the target core.
2508 ;     ESI - Pointer to an AP_EXE_PARAMS structure.
2509 ;
2510 ;           typedef struct {
2511 ;             IN OUT   AMD_CONFIG_PARAMS StdHeader;
2512 ;             IN       UINT32 FunctionNumber;
2513 ;             IN       VOID *RelatedDataBlock;
2514 ;             IN       UINT32 RelatedDataBlockLength;
2515 ;           } AP_EXE_PARAMS;
2516 ;
2517 ;   Exit:
2518 ;     After this hook, AGESA will display - AGESA_TESTPOINT - E9h
2519 ;     EAX - Contains the AGESA_STATUS return code.
2520 ;           AGESA_SUCCESS The function has completed successfully.
2521 ;           AGESA_UNSUPPORTED This is a required function, so this value
2522 ;                             being returned causes a critical error
2523 ;                             response value from the AGESAT software
2524 ;                             function and no memory initialized.
2525 ;           AGESA_WARNING The AP did not respond.
2526 ;
2527 ;   Modified:
2528 ;     EAX
2529 ;
2530 ;   Purpose:
2531 ;     This function is used after main memory has been initialized
2532 ;     and the host environment has taken control of AP task dispatching.
2533 ;     This function must cause the indicated function code to be executed
2534 ;     upon the specified Application Processor. This procedure must be
2535 ;     executed in 32-bit mode. This function is required to be implemented
2536 ;     in the host environment.
2537 ;
2538 ;   Dependencies:
2539 ;     The host environment must route execution to the target AP and
2540 ;     have that AP call the"AmdLateRunApTask" entry point.
2541 ;
2542 AmdRunFuncOnAp PROC NEAR PUBLIC
2543
2544     push  es
2545     mov   ax, SEG AmdRunCodeOnApDataPointer
2546     mov   es, ax
2547     mov   eax, (AP_EXE_PARAMS PTR [esi]).RelatedDataBlock
2548     mov   es:AmdRunCodeOnApDataPointer, eax
2549     mov   eax, (AP_EXE_PARAMS PTR [esi]).RelatedBlockLength
2550     mov   es:AmdRunCodeOnApDataSize, eax
2551     mov   eax, (AP_EXE_PARAMS PTR [esi]).FunctionNumber
2552     mov   es:AmdRunCodeOnApFunction, eax
2553     mov   eax, AGESA_UNSUPPORTED
2554     mov   es:AmdRunCodeOnApStatus, eax
2555     pop   es
2556
2557     call  myRunFuncOnAp
2558
2559     push  es
2560     mov   ax, SEG AmdRunCodeOnApStatus
2561     mov   es, ax
2562     mov   eax, es:AmdRunCodeOnApStatus
2563     pop   es
2564     ret
2565 AmdRunFuncOnAp ENDP
2566
2567
2568
2569 ;+---------------------------------------------------------------------------
2570 ;
2571 ;   AmdCalloutRouterPost
2572 ;
2573 ;   Entry:
2574 ;     ECX - Callout function number
2575 ;     EDX - Function-specific UINTN
2576 ;     ESI - Pointer to function specific data
2577 ;
2578 ;   Exit:
2579 ;     EAX - Contains the AGESA_STATUS return code.
2580 ;
2581 ;   Modified:
2582 ;     None
2583 ;
2584 ;   Purpose:
2585 ;     The call out router function for AmdInitEnv,
2586 ;     AmdInitMid, AmdInitLate, AmdS3Save, and
2587 ;     AmdS3LateRestore.
2588 ;
2589 ;   Dependencies:
2590 ;     None
2591 ;
2592 AmdCalloutRouterPost PROC FAR PUBLIC USES ECX EBX ESI BX DI DS ES
2593     xor   ax, ax
2594     mov   ds, ax
2595     mov   es, ax
2596     lea   di, cs:CalloutRouterTablePost
2597     mov   eax, AGESA_UNSUPPORTED
2598
2599 loopThruTable:
2600     cmp   di, OFFSET cs:CalloutRouterTablePostEnd
2601     jae   amdCpuCalloutExit ; exit with AGESA_UNSUPPORTED
2602     cmp   ecx, cs:[di].sOemCallout.FuncName
2603     je    FoundMatch
2604     add   di, SIZEOF sOemCallout
2605     jmp   loopThruTable
2606
2607 FoundMatch:
2608     mov   bx, cs:[di].sOemCallout.FuncPtr
2609     call  bx
2610
2611 amdCpuCalloutExit:
2612     ret
2613 AmdCalloutRouterPost ENDP
2614
2615
2616 ;----------------------------------------------------------------------------
2617 ; Define the callout dispatch table for the POST segment
2618 ;----------------------------------------------------------------------------
2619
2620 CalloutRouterTablePost LABEL BYTE
2621     ;; Add entries as desired.
2622     sOemCallout <AGESA_ALLOCATE_BUFFER, OFFSET myAllocateBuffer>
2623     sOemCallout <AGESA_DEALLOCATE_BUFFER, OFFSET myDeallocateBuffer>
2624     sOemCallout <AGESA_LOCATE_BUFFER, OFFSET myLocateBuffer>
2625     sOemCallout <AGESA_RUNFUNC_ONAP, OFFSET AmdRunFuncOnAp>
2626 CalloutRouterTablePostEnd LABEL BYTE
2627
2628 AMD_POST_END
2629
2630
2631 ;----------------------------------------------------------------------------
2632 ;    CPU DATA SEGMENT
2633 ; This segment must be writable, and present at the time that
2634 ; AmdInitLate is run.
2635 ;----------------------------------------------------------------------------
2636
2637 CPU_DATASEG_START
2638
2639   ;; Data used to store pointers for later use by the host environment.
2640   PUBLIC AmdAcpiSratPointer
2641   PUBLIC AmdAcpiSratSize
2642   PUBLIC AmdAcpiSlitPointer
2643   PUBLIC AmdAcpiSlitSize
2644   PUBLIC AmdAcpiSsdtPointer
2645   PUBLIC AmdAcpiSsdtSize
2646   PUBLIC AmdAcpiWheaMcePointer
2647   PUBLIC AmdAcpiWheaMceSize
2648   PUBLIC AmdAcpiWheaCmcPointer
2649   PUBLIC AmdAcpiWheaCmcSize
2650   PUBLIC AmdDmiInfoPointer
2651   AmdAcpiSratPointer     DWORD ?
2652   AmdAcpiSratSize        DWORD ?
2653   AmdAcpiSlitPointer     DWORD ?
2654   AmdAcpiSlitSize        DWORD ?
2655   AmdAcpiSsdtPointer     DWORD ?
2656   AmdAcpiSsdtSize        DWORD ?
2657   AmdAcpiWheaMcePointer  DWORD ?
2658   AmdAcpiWheaMceSize     DWORD ?
2659   AmdAcpiWheaCmcPointer  DWORD ?
2660   AmdAcpiWheaCmcSize     DWORD ?
2661   AmdDmiInfoPointer      DWORD ?
2662
2663   ;; Data used for communication between the AP and the BSP.
2664   PUBLIC AmdRunCodeOnApDataPointer
2665   PUBLIC AmdRunCodeOnApDataSize
2666   PUBLIC AmdRunCodeOnApFunction
2667   PUBLIC AmdRunCodeOnApStatus
2668   AmdRunCodeOnApDataPointer  DWORD ?
2669   AmdRunCodeOnApDataSize     DWORD ?
2670   AmdRunCodeOnApFunction     DWORD ?
2671   AmdRunCodeOnApStatus       DWORD ?
2672
2673 CPU_DATASEG_END
2674
2675
2676 END