blob: 98671f47d5f7674023a49b4feca2636cda727f4d [file] [log] [blame]
zbaof7223732012-04-13 13:42:15 +08001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2012 Advanced Micro Devices, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
Patrick Georgib890a122015-03-26 15:17:45 +010017 * Foundation, Inc.
zbaof7223732012-04-13 13:42:15 +080018 */
19
zbaof7223732012-04-13 13:42:15 +080020#include <console/console.h>
21#include <cpu/x86/msr.h>
22#include <cpu/x86/mtrr.h>
Kyösti Mälkki23b4f0c2014-06-18 09:55:26 +030023#include <cpu/amd/car.h>
zbaof7223732012-04-13 13:42:15 +080024#include <cpu/amd/mtrr.h>
25#include <cpu/x86/cache.h>
zbaof7223732012-04-13 13:42:15 +080026#include <cbmem.h>
zbaof7223732012-04-13 13:42:15 +080027#include <string.h>
Kyösti Mälkki920d17c2015-05-26 00:10:52 +030028#include <halt.h>
zbaof7223732012-04-13 13:42:15 +080029#include "s3_resume.h"
zbaof7223732012-04-13 13:42:15 +080030
Kyösti Mälkki23b4f0c2014-06-18 09:55:26 +030031static void *backup_resume(void)
zbaof7223732012-04-13 13:42:15 +080032{
zbaof7223732012-04-13 13:42:15 +080033 void *resume_backup_memory;
34
Kyösti Mälkki920d17c2015-05-26 00:10:52 +030035 printk(BIOS_DEBUG, "Find resume memory location\n");
36
37 if (cbmem_recovery(1)) {
38 printk(BIOS_EMERG, "Unable to recover CBMEM\n");
39 halt();
40 }
zbaof7223732012-04-13 13:42:15 +080041
42 resume_backup_memory = cbmem_find(CBMEM_ID_RESUME);
Kyösti Mälkki920d17c2015-05-26 00:10:52 +030043 if (resume_backup_memory == NULL) {
44 printk(BIOS_EMERG, "No storage for low-memory backup\n");
45 halt();
zbaof7223732012-04-13 13:42:15 +080046 }
47
48 return resume_backup_memory;
49}
50
Kyösti Mälkki23b4f0c2014-06-18 09:55:26 +030051static void move_stack_high_mem(void)
zbaof7223732012-04-13 13:42:15 +080052{
Kyösti Mälkkif7284082015-05-26 10:12:45 +030053 void *high_stack = cbmem_find(CBMEM_ID_ROMSTAGE_RAM_STACK);
zbaof7223732012-04-13 13:42:15 +080054
Kyösti Mälkkif7284082015-05-26 10:12:45 +030055 /* TODO: Make the switch with empty stack instead. */
56 memcpy(high_stack, (void *)BSP_STACK_BASE_ADDR, HIGH_ROMSTAGE_STACK_SIZE);
zbaof7223732012-04-13 13:42:15 +080057
Kyösti Mälkkif7284082015-05-26 10:12:45 +030058 /* TODO: We only switch stack on BSP. */
Stefan Reinauer67b94302015-06-18 01:14:01 -070059#ifdef __x86_64__
60 __asm__
61 volatile ("add %0, %%rsp; add %0, %%rbp; invd"::"g"
62 (high_stack - BSP_STACK_BASE_ADDR)
63 :);
64#else
zbaof7223732012-04-13 13:42:15 +080065 __asm__
66 volatile ("add %0, %%esp; add %0, %%ebp; invd"::"g"
67 (high_stack - BSP_STACK_BASE_ADDR)
68 :);
Stefan Reinauer67b94302015-06-18 01:14:01 -070069#endif
zbaof7223732012-04-13 13:42:15 +080070}
71
Kyösti Mälkki23b4f0c2014-06-18 09:55:26 +030072static void set_resume_cache(void)
zbaof7223732012-04-13 13:42:15 +080073{
74 msr_t msr;
75
76 /* disable fixed mtrr for now, it will be enabled by mtrr restore */
77 msr = rdmsr(SYSCFG_MSR);
78 msr.lo &= ~(SYSCFG_MSR_MtrrFixDramEn | SYSCFG_MSR_MtrrFixDramModEn);
79 wrmsr(SYSCFG_MSR, msr);
80
81 /* Enable caching for 0 - coreboot ram using variable mtrr */
82 msr.lo = 0 | MTRR_TYPE_WRBACK;
83 msr.hi = 0;
84 wrmsr(MTRRphysBase_MSR(0), msr);
85 msr.lo = ~(CONFIG_RAMTOP - 1) | MTRRphysMaskValid;
86 msr.hi = (1 << (CONFIG_CPU_ADDR_BITS - 32)) - 1;
87 wrmsr(MTRRphysMask_MSR(0), msr);
88
89 /* Set the default memory type and disable fixed and enable variable MTRRs */
90 msr.hi = 0;
91 msr.lo = (1 << 11);
92 wrmsr(MTRRdefType_MSR, msr);
93
94 enable_cache();
95}
96
Kyösti Mälkki23b4f0c2014-06-18 09:55:26 +030097void prepare_for_resume(void)
zbaof7223732012-04-13 13:42:15 +080098{
Kyösti Mälkki23b4f0c2014-06-18 09:55:26 +030099 void *resume_backup_memory = backup_resume();
zbaof7223732012-04-13 13:42:15 +0800100
Kyösti Mälkki23b4f0c2014-06-18 09:55:26 +0300101 post_code(0x62);
102 printk(BIOS_DEBUG, "Move CAR stack.\n");
103 move_stack_high_mem();
Kyösti Mälkki23b4f0c2014-06-18 09:55:26 +0300104
105 post_code(0x63);
106 disable_cache_as_ram();
107 printk(BIOS_DEBUG, "CAR disabled.\n");
108 set_resume_cache();
109
110 /*
111 * Copy the system memory that is in the ramstage area to the
112 * reserved area.
113 */
114 if (resume_backup_memory)
115 memcpy(resume_backup_memory, (void *)(CONFIG_RAMBASE), HIGH_MEMORY_SAVE);
116
117 printk(BIOS_DEBUG, "System memory saved. OK to load ramstage.\n");
zbaof7223732012-04-13 13:42:15 +0800118}