| /* |
| * This file is part of the coreboot project. |
| * |
| * Copyright (C) 2000,2007 Ronald G. Minnich <rminnich@gmail.com> |
| * Copyright (C) 2007-2008 coresystems GmbH |
| * Copyright (C) 2013-2014 Sage Electronic Engineering, LLC. |
| * Copyright (C) 2015 Intel Corp. |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published by |
| * the Free Software Foundation; version 2 of the License. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| */ |
| |
| #include <cpu/x86/mtrr.h> |
| #include <cpu/x86/cache.h> |
| #include <cpu/x86/post_code.h> |
| |
| /* |
| * This is the common entry point after DRAM has been initialized. |
| */ |
| /* |
| * eax: New stack address |
| */ |
| |
| /* Switch to the stack in RAM */ |
| movl %eax, %esp |
| |
| #if IS_ENABLED(CONFIG_SKIP_FSP_CAR) |
| |
| /* chipset_teardown_car() is expected to disable cache-as-ram. */ |
| call chipset_teardown_car |
| |
| #else |
| .extern fih_car |
| |
| post_code(POST_FSP_TEMP_RAM_EXIT) |
| |
| /* Calculate TempRamExit entry into FSP */ |
| movl fih_car, %ebp |
| mov 0x40(%ebp), %eax |
| add 0x1c(%ebp), %eax |
| |
| /* Build the call frame */ |
| pushl $0 |
| |
| /* Call TempRamExit */ |
| call *%eax |
| add $4, %esp |
| cmp $0, %eax |
| jz 1f |
| /* |
| * Failures for post code BC - failed in TempRamExit |
| * |
| * 0x00 - FSP_SUCCESS: Temp RAM Exit completed successfully. |
| * 0x02 - FSP_INVALID_PARAMETER: Input parameters are invalid. |
| * 0x03 - FSP_UNSUPPORTED: The FSP calling conditions were not met. |
| * 0x07 - FSP_DEVICE_ERROR: Temp RAM Exit failed. |
| */ |
| movb $0xBC, %ah |
| jmp .Lhlt |
| 1: |
| #endif |
| /* Display the MTRRs */ |
| call display_mtrrs |
| |
| /* |
| * The stack contents are initialized in src/soc/intel/common/stack.c |
| * to be the following: |
| * |
| * * |
| * * |
| * * |
| * +36: MTRR mask 1 63:32 |
| * +32: MTRR mask 1 31:0 |
| * +28: MTRR base 1 63:32 |
| * +24: MTRR base 1 31:0 |
| * +20: MTRR mask 0 63:32 |
| * +16: MTRR mask 0 31:0 |
| * +12: MTRR base 0 63:32 |
| * +8: MTRR base 0 31:0 |
| * +4: Number of MTRRs to setup (described above) |
| * +0: Number of variable MTRRs to clear |
| */ |
| |
| #if IS_ENABLED(CONFIG_SOC_SETS_MSRS) |
| push %esp |
| call soc_set_mtrrs |
| |
| /* eax: new top_of_stack with setup_stack_and_mtrrs data removed */ |
| movl %eax, %esp |
| #else |
| /* Clear all of the variable MTRRs. */ |
| popl %ebx |
| movl $MTRR_PHYS_BASE(0), %ecx |
| clr %eax |
| clr %edx |
| |
| 1: |
| testl %ebx, %ebx |
| jz 1f |
| wrmsr /* Write MTRR base. */ |
| inc %ecx |
| wrmsr /* Write MTRR mask. */ |
| inc %ecx |
| dec %ebx |
| jmp 1b |
| |
| 1: |
| /* Get number of MTRRs. */ |
| popl %ebx |
| movl $MTRR_PHYS_BASE(0), %ecx |
| 2: |
| testl %ebx, %ebx |
| jz 2f |
| |
| /* Low 32 bits of MTRR base. */ |
| popl %eax |
| /* Upper 32 bits of MTRR base. */ |
| popl %edx |
| /* Write MTRR base. */ |
| wrmsr |
| inc %ecx |
| /* Low 32 bits of MTRR mask. */ |
| popl %eax |
| /* Upper 32 bits of MTRR mask. */ |
| popl %edx |
| /* Write MTRR mask. */ |
| wrmsr |
| inc %ecx |
| |
| dec %ebx |
| jmp 2b |
| 2: |
| #endif /* CONFIG_SOC_SETS_MSRS */ |
| |
| post_code(0x39) |
| |
| /* And enable cache again after setting MTRRs. */ |
| movl %cr0, %eax |
| andl $~(CR0_CacheDisable | CR0_NoWriteThrough), %eax |
| movl %eax, %cr0 |
| |
| post_code(0x3a) |
| |
| #if IS_ENABLED(CONFIG_SOC_SETS_MSRS) |
| call soc_enable_mtrrs |
| #else |
| /* Enable MTRR. */ |
| movl $MTRR_DEF_TYPE_MSR, %ecx |
| rdmsr |
| orl $MTRR_DEF_TYPE_EN, %eax |
| wrmsr |
| #endif /* CONFIG_SOC_SETS_MSRS */ |
| |
| post_code(0x3b) |
| |
| /* Invalidate the cache again. */ |
| invd |
| |
| post_code(0x3c) |
| |
| __main: |
| post_code(POST_PREPARE_RAMSTAGE) |
| cld /* Clear direction flag. */ |
| call after_cache_as_ram |