| ;***************************************************************************** |
| ; AMD Generic Encapsulated Software Architecture |
| ; |
| ; Workfile: cpcarmac.inc $Revision:: 44323 $ $Date:: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 2010) $ |
| ; |
| ; Description: Code to setup and break down cache-as-stack |
| ; |
| ;***************************************************************************** |
| ; |
| ; Copyright (c) 2011, Advanced Micro Devices, Inc. |
| ; All rights reserved. |
| ; |
| ; Redistribution and use in source and binary forms, with or without |
| ; modification, are permitted provided that the following conditions are met: |
| ; * Redistributions of source code must retain the above copyright |
| ; notice, this list of conditions and the following disclaimer. |
| ; * Redistributions in binary form must reproduce the above copyright |
| ; notice, this list of conditions and the following disclaimer in the |
| ; documentation and/or other materials provided with the distribution. |
| ; * Neither the name of Advanced Micro Devices, Inc. nor the names of |
| ; its contributors may be used to endorse or promote products derived |
| ; from this software without specific prior written permission. |
| ; |
| ; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| ; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| ; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| ; DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY |
| ; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| ; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| ; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| ; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| ; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| ; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| ; |
| ;***************************************************************************** |
| |
| .XLIST |
| INCLUDE cpcar.inc |
| .LIST |
| .586P |
| |
| ;====================================================================== |
| ; AMD_ENABLE_STACK: Setup a stack |
| ; |
| ; In: |
| ; none |
| ; |
| ; Out: |
| ; SS:ESP - Our new private stack location |
| ; 4000:3FFC - for BSP (16K Stack) |
| ; 4000:7FFC - for core0 of node1 (16K Stack) |
| ; 4000:BFFC - for core0 of node2 (16K Stack) |
| ; 4000:FFFC - for core0 of node3 (16K Stack) |
| ; 5000:3FFC - for core0 of node4 (16K Stack) |
| ; 5000:7FFC - for core0 of node5 (16K Stack) |
| ; 5000:BFFC - for core0 of node6 (16K Stack) |
| ; 5000:FFFC - for core0 of node7 (16K Stack) |
| ; |
| ; 6000:1FFC - for core1 node0 (4k stack) |
| ; 6000:2FFC - for core2 node0 (4k stack) |
| ; ... |
| ; 9000:8FFC - for core7 of node7 (4k stack) ......... max of 64 cores in system |
| ; |
| ; EAX = AGESA_STATUS |
| ; |
| ; ECX = Stack size in bytes |
| ; |
| ; Requirements: |
| ; * This routine presently is limited to a max of 64 processors |
| ; |
| ; Preserved: |
| ; ebx |
| ; Destroyed: |
| ; eax, ecx, edx, edi, esi, ds, es |
| ; |
| ;====================================================================== |
| AMD_ENABLE_STACK MACRO |
| |
| local SetupStack |
| local SetupDramMap |
| local get_SS_ESP |
| local r16bmode |
| local p32mode |
| local init_stack |
| |
| ; Note that SS:ESP will be default stack. Note that this stack |
| ; routine will not be used after memory has been initialized. Because |
| ; of its limited lifetime, it will not conflict with typical PCI devices. |
| |
| mov esp, ebx ; put return address in a safe place |
| |
| ; get node id and core id of current executing core |
| mov si, -1 |
| GET_NODE_ID_CORE_ID |
| movzx edi, di |
| |
| ; determine if stack is already enabled. |
| mov eax, cr0 |
| test eax, 60000000h |
| jnz SetupStack |
| mov ecx, AMD_MTRR_DEFTYPE |
| _RDMSR |
| test ah, 0Ch |
| jz SetupStack |
| or edi, 0FFFF0000h ; indicate stack has already been initialized |
| jmp get_SS_ESP |
| |
| SetupStack: |
| ; Enable routing tables on BSP (just in case the HT init code has not yet enabled them) |
| mov eax, 8000C06Ch |
| mov dx, 0CF8h |
| out dx, eax |
| add dx, 4 |
| in eax, dx |
| btr eax, 0 |
| out dx, eax |
| |
| ; Setup temporary DRAM map for CAS on all nodes |
| mov eax, 8000C060h ; Get NodeCnt from BSP |
| mov dx, 0CF8h |
| out dx, eax |
| add dx, 4 |
| in al, dx |
| shr ax, 4 |
| and al, 7 |
| mov cl, al |
| |
| mov ebx, 8000C144h |
| SetupDramMap: |
| mov eax, ebx ; Set 0000_0000 to 00FF_FFFF as DRAM |
| mov dx, 0CF8h |
| out dx, eax |
| add dx, 4 |
| mov eax, 0 |
| out dx, eax |
| |
| mov eax, ebx |
| sub eax, 4 |
| mov dx, 0CF8h |
| out dx, eax |
| add dx, 4 |
| mov eax, 3 |
| out dx, eax |
| |
| add bh, 8 |
| dec cl |
| jns SetupDramMap |
| |
| ; Disable the self modifying code check buffer and Disable hardware prefetches |
| mov ecx, 0C0011022h |
| _RDMSR |
| bts eax, DC_DIS_SPEC_TLB_RLD ; turn on Disable speculative TLB reloads bit |
| bts eax, DIS_CLR_WBTOL2_SMC_HIT ; turn on Disable the self modifying code check buffer bit |
| bts eax, DIS_HW_PF ; turn on Disable hardware prefetches bit |
| _WRMSR |
| dec cx ; MSRC001_1021 Instruction Cache Configuration Register (IC_CFG) |
| _RDMSR |
| bts eax, IC_DIS_SPEC_TLB_RLD ; turn on Disable speculative TLB reloads bit |
| _WRMSR |
| |
| AMD_ENABLE_STACK_FAMILY_HOOK ; Disable L3 cache to accept clear lines |
| |
| ; Init CPU MSRs for our init routines |
| mov ecx, MTRR_SYS_CFG ; SYS_CFG |
| _RDMSR |
| and eax, 0FFE3FFFFh ; turn off MTRR enable bits |
| bts eax, MtrrFixDramModEn ; turn on modification enable bit |
| _WRMSR |
| |
| ; clear all variable and Fixed MTRRs |
| mov ecx, 200h |
| xor eax, eax |
| xor edx, edx |
| .while (cl != 10h) ; MTRRphysBasen and MTRRphysMaskn |
| _WRMSR |
| inc cl |
| .endw |
| mov cl, 50h ; MTRRfix64K_00000 |
| _WRMSR |
| mov cl, 58h ; MTRRfix16K_80000 |
| _WRMSR |
| mov cl, 59h ; MTRRfix16K_A0000 |
| _WRMSR |
| mov cl, 68h ; MTRRfix4K_C0000 to MTRRfix4K_F8000 |
| .while (cl != 70h) |
| _WRMSR |
| inc cl |
| .endw |
| |
| ; setup MTTR for stacks |
| mov ebx, WB_DRAM_TYPE |
| .if (di == 0) ;core 0 |
| .if (si > 3) ; node 0 to 3 located at 40000h, node 4 to 7 located at 50000h |
| shl ebx, 8 |
| .endif |
| mov ecx, AMD_MTRR_FIX64k_00000 |
| _RDMSR |
| or edx, ebx |
| _WRMSR |
| .else ;core 1 to core 7 start at 60000h |
| .if (si < 4) ; node 0 to 3 using AMD_MTRR_FIX64K_6000 and AMD_MTRR_FIX64K_7000 MTTR |
| shl ebx, 16 |
| .if (si > 1) |
| shl ebx, 8 |
| .endif |
| mov ecx, AMD_MTRR_FIX64k_00000 |
| _RDMSR |
| or edx, ebx |
| _WRMSR |
| .else ; node 4 to 7 uses AMD_MTRR_FIX16K_80000 and AMD_MTRR_FIX16K_9000 MTTR |
| mov ecx, AMD_MTRR_FIX16k_80000 |
| _RDMSR |
| .if (si < 6) ; node 4 and node 5 |
| .if (si == 4) ; node 4 |
| .if (di >= 4) |
| shl ebx, 8 |
| .endif |
| .else ; node 5 |
| shl ebx, 16 |
| .if (di >= 4) |
| shl ebx, 8 |
| .endif |
| .endif |
| or eax, ebx |
| _WRMSR |
| .else ; node 6 and node 7 |
| .if (si == 6) ; node 6 |
| .if (di >= 4) |
| shl ebx, 8 |
| .endif |
| .else ; node 7 |
| shl ebx, 16 |
| .if (di >= 4) |
| shl ebx, 8 |
| .endif |
| .endif |
| or edx, ebx |
| _WRMSR |
| .endif |
| .endif |
| .endif |
| |
| ; Clear IORRs, TOP_MEM and TOM2 |
| xor eax, eax |
| xor edx, edx |
| |
| mov ecx, 0C0010016h ;IORRBase0 |
| .while (cl != 1Bh) |
| _WRMSR |
| inc cl |
| .endw |
| mov cl, 1Dh |
| _WRMSR |
| |
| ; Enable MTRRs |
| mov ecx, 02FFh ; MTRRdefType |
| mov ah, 0Ch ; MtrrDefTypeEn and MtrrDefTypeFixEn |
| _WRMSR |
| |
| mov ecx, MTRR_SYS_CFG ; SYS_CFG |
| _RDMSR |
| bts eax, MtrrFixDramEn ; MtrrFixDramEn |
| btr eax, MtrrFixDramModEn ; turn off modification enable bit |
| _WRMSR |
| |
| ; Enable caching in CR0 |
| mov eax, CR0 ; Enable WT/WB cache |
| btr eax, 31 ; make sure paging is disabled |
| btr eax, 30 ; Clear CR0 NW and CD |
| btr eax, 29 |
| mov CR0, eax |
| |
| get_SS_ESP: |
| ; allocate space for stacks |
| xor cx, cx |
| xor edx, edx |
| .if (di == 0) ;core 0 |
| mov eax, CORE0_STACK_BASE_ADDR |
| .while (cx <= si) |
| add eax, 4000h |
| inc cx |
| .endw |
| mov edx, eax |
| sub eax, 4000h |
| and eax, 0F0000h |
| sub edx, 4 |
| and edx, 0FFFFh |
| mov bx, CORE0_STACK_SIZE / 4 |
| .else ;core 1 to core 7 start at 60000h |
| mov eax, CORE1_STACK_BASE_ADDR ; core 1 stack starts at 60000h |
| .while (cx <= si) |
| add eax, 8000h ; 32k for each node |
| inc cx |
| .endw |
| sub eax, 8000h |
| mov dx, ax |
| and eax, 0F0000h |
| xor cx, cx |
| .while (cx <= di) |
| add edx, 1000h ; 4k for APs |
| inc cx |
| .endw |
| sub edx, 4 |
| mov bx, CORE1_STACK_SIZE / 4 |
| .endif |
| |
| ; Allocate stack and set ESP |
| mov ecx, CR0 ; check for 32-bit protect mode |
| test ecx, 1 ; PE bit |
| jz r16bmode ; PE=0, real mode |
| mov cx, cs ; PE=1 |
| cmp cx, 0D000h ; check for CS |
| jb p32mode ; if CS < D000, it is a selector instead of a segment |
| r16bmode: |
| shr eax, 4 ; ax = ss, ds, es |
| mov ss, ax |
| mov ds, ax |
| mov es, ax |
| jmp init_stack |
| p32mode: |
| add edx, eax ; linear address of the stack |
| init_stack: |
| |
| .if ( !(edi & 0FFFF0000h)) |
| std |
| xor ecx, ecx |
| mov cx, bx |
| mov esi, edx |
| rep lods DWORD PTR [esi] |
| xor eax, eax |
| mov cx, bx |
| mov edi, edx |
| rep stos DWORD PTR [edi] |
| cld |
| xor eax, eax ; eax = 0 : no error |
| .else |
| mov eax, 40000001h ; eax = AGESA_WARNING (Stack has already been set up) |
| .endif |
| |
| mov cx, bx ; ecx = size in dwords |
| shl ecx, 2 ; ecx = size in bytes |
| |
| mov ebx, esp |
| mov esp, edx |
| |
| |
| ENDM |
| |
| ;====================================================================== |
| ; AMD_DISABLE_STACK: Destroy the stack inside the cache. This routine |
| ; should only be executed on the BSP |
| ; |
| ; In: |
| ; none |
| ; |
| ; Out: |
| ; EAX = AGESA_STATUS |
| ; |
| ; Preserved: |
| ; ebx |
| ; Destroyed: |
| ; eax, ecx, edx, esp |
| ;====================================================================== |
| AMD_DISABLE_STACK MACRO |
| |
| mov esp, ebx ; save return address |
| |
| ; Turn on modification enable bit |
| mov ecx, MTRR_SYS_CFG |
| _RDMSR |
| bts eax, MtrrFixDramModEn ; Enable |
| _WRMSR |
| |
| ; Disable MTRRs and turn on modification enable bit |
| mov ecx,AMD_MTRR_FIX64k_00000 |
| mov eax,1E1E1E1Eh |
| mov edx,eax |
| _WRMSR ; 0 - 512K = WB Mem |
| mov cl,58h |
| _WRMSR ; 512K - 640K = WB Mem |
| |
| ; Turn off modification enable bit |
| mov ecx, MTRR_SYS_CFG |
| _RDMSR |
| btr eax, MtrrFixDramModEn ; Disable |
| _WRMSR |
| |
| ; Enable the self modifying code check buffer and Enable hardware prefetches |
| mov ecx, 0C0011022h |
| _RDMSR |
| btr eax, DC_DIS_SPEC_TLB_RLD ; Disable speculative TLB reloads bit |
| btr eax, DIS_CLR_WBTOL2_SMC_HIT ; Disable the self modifying code check buffer bit |
| btr eax, DIS_HW_PF ; Disable hardware prefetches bit |
| _WRMSR |
| |
| dec cx ; MSRC001_1021 Instruction Cache Configuration Register (IC_CFG) |
| _RDMSR |
| btr eax, IC_DIS_SPEC_TLB_RLD ; turn on Disable speculative TLB reloads bit |
| _WRMSR |
| |
| AMD_DISABLE_STACK_FAMILY_HOOK ; Re-Enable L3 cache to accept clear lines |
| |
| mov ebx, esp |
| xor eax, eax |
| |
| ENDM |