| /* |
| * 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. |
| * |
| */ |
| |
| .include "src/vendorcode/amd/agesa/f16kb/gcccar.inc" |
| |
| .code32 |
| .align 4 |
| .globl ExecuteFinalHltInstruction |
| .type ExecuteFinalHltInstruction, @function |
| |
| /* This function disables CAR. We don't care about the stack on this CPU */ |
| ExecuteFinalHltInstruction: |
| movl 4(%esp), %esi /* HaltFlags*/ |
| movl 8(%esp), %edi /* ApMtrrSettingList */ |
| |
| /* Do these special steps in case if the core is part of a compute unit |
| * Note: The following bits are family specific flags, that gets set during build time, |
| * and indicates things like "family cache control methodology", etc. |
| * esi bit0 = 0 -> not a Primary core |
| * esi bit0 = 1 -> Primary core |
| * esi bit1 = 0 -> Cache disable |
| * esi bit1 = 1 -> Cache enable |
| */ |
| |
| bt $1, %esi /* .if (esi & 2h) */ |
| jz 0f |
| /* TODO: Set CombineCr0Cd bit */ |
| //movl $CU_CFG3, %ecx |
| //rdmsr |
| //bts $(COMBINE_CR0_CD - 32), %edx |
| //wrmsr |
| /* Clear the CR0.CD bit */ |
| movl %cr0, %eax /* Make sure cache is enabled for all APs */ |
| btr $CR0_CD, %eax |
| btr $CR0_NW, %eax |
| mov %eax, %cr0 /* Write back to CR0 */ |
| jmp 1f /* .else */ |
| 0: |
| movl %cr0, %eax /* Make sure cache is disabled for all APs */ |
| bts $CR0_CD, %eax /* Disable cache */ |
| bts $CR0_NW, %eax |
| movl %eax, %cr0 /* Write back to CR0 */ |
| 1: /* .endif */ |
| |
| bt $0, %esi /* .if (esi & 1h) */ |
| jz 2f |
| /* This core is a primary core and needs to do all the MTRRs, including shared MTRRs. */ |
| movl %edi, %esi /* Get ApMtrrSettingList */ |
| |
| /* Configure the MTRRs on the AP so |
| * when it runs remote code it will execute |
| * out of RAM instead of ROM. |
| */ |
| |
| /* Disable MTRRs and turn on modification enable bit */ |
| movl $MTRR_SYS_CFG, %ecx |
| rdmsr |
| /* TODO: why comment this? */ |
| btr $MTRR_VAR_DRAM_EN, %eax /* Disable */ |
| bts $MTRR_FIX_DRAM_MOD_EN, %eax /* Enable */ |
| btr $MTRR_FIX_DRAM_EN, %eax /* Disable */ |
| bts $SYS_UC_LOCK_EN, %eax |
| wrmsr |
| |
| /* Setup default values for Fixed-Sized MTRRs */ |
| /* Set 7FFFh-00000h as WB */ |
| movl $AMD_AP_MTRR_FIX64k_00000, %ecx |
| movl $0x1E1E1E1E, %eax |
| movl %eax, %edx |
| wrmsr |
| |
| /* Set 9FFFFh-80000h also as WB */ |
| movl $AMD_AP_MTRR_FIX16k_80000, %ecx |
| wrmsr |
| |
| /* Set BFFFFh-A0000h as Uncacheable Memory-mapped IO */ |
| movl $AMD_AP_MTRR_FIX16k_A0000, %ecx |
| xorl %eax, %eax |
| xorl %edx, %edx |
| wrmsr |
| |
| /* Set DFFFFh-C0000h as Uncacheable Memory-mapped IO */ |
| xorl %eax, %eax |
| xorl %edx, %edx |
| movl $AMD_AP_MTRR_FIX4k_C0000, %ecx |
| |
| CDLoop: |
| wrmsr |
| inc %ecx |
| cmp $AMD_AP_MTRR_FIX4k_D8000, %ecx |
| jbe CDLoop |
| |
| /* Set FFFFFh-E0000h as Uncacheable Memory */ |
| movl $0x18181818, %eax |
| movl %eax, %edx |
| |
| mov $AMD_AP_MTRR_FIX4k_E0000, %ecx |
| |
| EFLoop: |
| wrmsr |
| inc %ecx |
| cmp $AMD_AP_MTRR_FIX4k_F8000, %ecx |
| jbe EFLoop |
| |
| /* If IBV provided settings for Fixed-Sized MTRRs, |
| * overwrite the default settings. */ |
| cmp $0, %esi /*.if ((esi != 0) && (esi != 0FFFFFFFFh)) */ |
| jz 4f |
| cmp $0xFFFFFFFF, %esi |
| jz 4f |
| 5: |
| mov (%esi), %ecx /* (AP_MTRR_SETTINGS ptr [esi]).MsrAddr */ |
| /* While we are not at the end of the list */ |
| cmp $CPU_LIST_TERMINAL, %ecx /* .while (ecx != CPU_LIST_TERMINAL)*/ |
| je 4f |
| /* TODO - coreboot isn't checking for valid data. |
| * Ensure that the MSR address is valid for Fixed-Sized MTRRs */ |
| /*.if ( ((ecx >= AMD_AP_MTRR_FIX4k_C0000) && (ecx <= AMD_AP_MTRR_FIX4k_F8000)) || \ |
| (ecx == AMD_AP_MTRR_FIX64k_00000) || (ecx == AMD_AP_MTRR_FIX16k_80000 ) || \ |
| (ecx == AMD_AP_MTRR_FIX16k_A0000)) |
| */ |
| mov 4(%esi), %eax /* MsrData */ |
| mov 8(%esi), %edx /* MsrData */ |
| wrmsr |
| /* .endif */ |
| add $12, %esi /* sizeof (AP_MTRR_SETTINGS) */ |
| jmp 5b /* .endw */ |
| 4: /* .endif */ |
| |
| /* Enable fixed-range and variable-range MTRRs */ |
| mov $AMD_MTRR_DEFTYPE, %ecx |
| rdmsr |
| bts $MTRR_DEF_TYPE_EN, %eax /* MtrrDefTypeEn */ |
| bts $MTRR_DEF_TYPE_FIX_EN, %eax /* MtrrDefTypeFixEn */ |
| wrmsr |
| |
| /* Enable Top-of-Memory setting */ |
| /* Enable use of RdMem/WrMem bits attributes */ |
| mov $MTRR_SYS_CFG, %ecx |
| rdmsr |
| /* TODO: */ |
| bts $MTRR_VAR_DRAM_EN, %eax /* Enable */ |
| btr $MTRR_FIX_DRAM_MOD_EN, %eax /* Disable */ |
| bts $MTRR_FIX_DRAM_EN, %eax /* Enable */ |
| wrmsr |
| |
| bts $FLAG_IS_PRIMARY, %esi |
| jmp 3f /* .else ; end if primary core */ |
| 2: |
| xor %esi, %esi |
| 3: /* .endif*/ |
| |
| /* Make sure not to touch any Shared MSR from this point on */ |
| |
| AMD_DISABLE_STACK_FAMILY_HOOK |
| |
| /* restore variable MTRR6 and MTRR7 to default states */ |
| bt $FLAG_IS_PRIMARY, %esi /* .if (esi & 1h) */ |
| jz 6f |
| movl $AMD_MTRR_VARIABLE_MASK7, %ecx /* clear MTRRPhysBase6 MTRRPhysMask6 */ |
| xor %eax, %eax /* and MTRRPhysBase7 MTRRPhysMask7 */ |
| xor %edx, %edx |
| cmp $AMD_MTRR_VARIABLE_BASE6, %ecx /* .while (cl < 010h) */ |
| jl 6f |
| wrmsr |
| dec %ecx |
| 6: /* .endw */ |
| |
| xor %eax, %eax |
| |
| 7: |
| cli |
| hlt |
| jmp 7b /* ExecuteHltInstruction */ |
| |
| .size ExecuteFinalHltInstruction, .-ExecuteFinalHltInstruction |