| /* |
| * This file is part of the coreboot project. |
| * |
| * Copyright (C) 2011 Advanced Micro Devices, Inc. |
| * |
| * 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. |
| */ |
| |
| /****************************************************************************** |
| * AMD Generic Encapsulated Software Architecture |
| * |
| * $Workfile:: cache_as_ram.inc |
| * |
| * Description: cache_as_ram.inc - AGESA Module Entry Point for GCC complier |
| * |
| ****************************************************************************** |
| */ |
| |
| #include "gcccar.inc" |
| #include <cpu/x86/cache.h> |
| |
| /* |
| * XMM map: |
| * xmm0: BIST |
| * xmm1: backup ebx -- cpu_init_detected |
| */ |
| |
| .code32 |
| .globl cache_as_ram_setup, disable_cache_as_ram, cache_as_ram_setup_out |
| |
| cache_as_ram_setup: |
| |
| post_code(0xa0) |
| |
| /* enable SSE2 128bit instructions */ |
| /* Turn on OSFXSR [BIT9] and OSXMMEXCPT [BIT10] onto CR4 register */ |
| |
| movl %cr4, %eax |
| orl $(3<<9), %eax |
| movl %eax, %cr4 |
| |
| /* Get the cpu_init_detected */ |
| mov $1, %eax |
| cpuid |
| shr $24, %ebx |
| |
| /* Save the BIST result */ |
| cvtsi2sd %ebp, %xmm0 |
| |
| /* for normal part %ebx already contain cpu_init_detected from fallback call */ |
| |
| /* Save the cpu_init_detected */ |
| cvtsi2sd %ebx, %xmm1 |
| |
| post_code(0xa1) |
| |
| AMD_ENABLE_STACK |
| |
| /* Align the stack. */ |
| and $0xFFFFFFF0, %esp |
| |
| #ifdef __x86_64__ |
| /* switch to 64 bit long mode */ |
| mov %esi, %ecx |
| add $0, %ecx # core number |
| xor %eax, %eax |
| lea (0x1000+0x23)(%ecx), %edi |
| mov %edi, (%ecx) |
| mov %eax, 4(%ecx) |
| |
| lea 0x1000(%ecx), %edi |
| movl $0x000000e3, 0x00(%edi) |
| movl %eax, 0x04(%edi) |
| movl $0x400000e3, 0x08(%edi) |
| movl %eax, 0x0c(%edi) |
| movl $0x800000e3, 0x10(%edi) |
| movl %eax, 0x14(%edi) |
| movl $0xc00000e3, 0x18(%edi) |
| movl %eax, 0x1c(%edi) |
| |
| # load ROM based identity mapped page tables |
| mov %ecx, %eax |
| mov %eax, %cr3 |
| |
| # enable PAE |
| mov %cr4, %eax |
| bts $5, %eax |
| mov %eax, %cr4 |
| |
| # enable long mode |
| mov $0xC0000080, %ecx |
| rdmsr |
| bts $8, %eax |
| wrmsr |
| |
| # enable paging |
| mov %cr0, %eax |
| bts $31, %eax |
| mov %eax, %cr0 |
| |
| # use call far to switch to 64-bit code segment |
| ljmp $0x18, $1f |
| 1: |
| /* Pass the cpu_init_detected */ |
| cvtsd2si %xmm1, %esi |
| |
| /* Pass the BIST result */ |
| cvtsd2si %xmm0, %edi |
| |
| |
| .code64 |
| call cache_as_ram_main |
| .code32 |
| |
| #else |
| |
| /* Restore the BIST result */ |
| cvtsd2si %xmm0, %edx |
| |
| /* Restore the cpu_init_detected */ |
| cvtsd2si %xmm1, %ebx |
| |
| /* Must maintain 16-byte stack alignment here. */ |
| pushl $0x0 |
| pushl $0x0 |
| pushl %ebx /* init detected */ |
| pushl %edx /* bist */ |
| call cache_as_ram_main |
| #endif |
| |
| /* Should never see this postcode */ |
| post_code(0xaf) |
| stop: |
| jmp stop |
| |
| disable_cache_as_ram: |
| /* Save return stack */ |
| movd 0(%esp), %xmm1 |
| movd %esp, %xmm0 |
| |
| /* Disable cache */ |
| movl %cr0, %eax |
| orl $CR0_CacheDisable, %eax |
| movl %eax, %cr0 |
| |
| AMD_DISABLE_STACK |
| |
| /* enable cache */ |
| movl %cr0, %eax |
| andl $0x9fffffff, %eax |
| movl %eax, %cr0 |
| xorl %eax, %eax |
| |
| /* Restore the return stack */ |
| wbinvd |
| movd %xmm0, %esp |
| movd %xmm1, (%esp) |
| ret |
| |
| cache_as_ram_setup_out: |
| #ifdef __x86_64__ |
| .code64 |
| #endif |