blob: f7119d1cf30d19706a20589932c1f5ed31983aa3 [file] [log] [blame]
;*****************************************************************************
; 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