blob: c87b70109fb452c98fbd4f4544b7f4e0d00a26b9 [file] [log] [blame]
Stefan Reinauercadc5452010-12-18 23:29:37 +00001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2010 coresystems GmbH
5 * Copyright (C) 2010 Rudolf Marek
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
Stefan Reinauercadc5452010-12-18 23:29:37 +000015 */
16
17#include <console/console.h>
18#include <arch/io.h>
19#include <cpu/cpu.h>
20#include <cpu/x86/lapic.h>
21#include <cpu/x86/msr.h>
22#include <cpu/x86/mtrr.h>
23#include <cpu/amd/mtrr.h>
Stefan Reinauer991f1842015-11-22 23:40:29 +010024#include <cpu/amd/msr.h>
Stefan Reinauercadc5452010-12-18 23:29:37 +000025#include <cpu/x86/cache.h>
26#include <cpu/x86/smm.h>
27#include <string.h>
28
Stefan Reinauercadc5452010-12-18 23:29:37 +000029extern unsigned char _binary_smm_start;
30extern unsigned char _binary_smm_size;
31
Stefan Reinauercadc5452010-12-18 23:29:37 +000032void smm_init(void)
33{
Rudolf Marekb5b3b3b2011-07-02 16:36:17 +020034 msr_t msr, syscfg_orig, mtrr_aseg_orig;
Stefan Reinauercadc5452010-12-18 23:29:37 +000035
Rudolf Marekb5b3b3b2011-07-02 16:36:17 +020036 /* Back up MSRs for later restore */
37 syscfg_orig = rdmsr(SYSCFG_MSR);
Alexandru Gagniuc86091f92015-09-30 20:23:09 -070038 mtrr_aseg_orig = rdmsr(MTRR_FIX_16K_A0000);
Stefan Reinauercadc5452010-12-18 23:29:37 +000039
Rudolf Marekb5b3b3b2011-07-02 16:36:17 +020040 /* MTRR changes don't like an enabled cache */
41 disable_cache();
Stefan Reinauercadc5452010-12-18 23:29:37 +000042
Rudolf Marekb5b3b3b2011-07-02 16:36:17 +020043 msr = syscfg_orig;
Stefan Reinauercadc5452010-12-18 23:29:37 +000044
Rudolf Marekb5b3b3b2011-07-02 16:36:17 +020045 /* Allow changes to MTRR extended attributes */
46 msr.lo |= SYSCFG_MSR_MtrrFixDramModEn;
47 /* turn the extended attributes off until we fix
48 * them so A0000 is routed to memory
49 */
50 msr.lo &= ~SYSCFG_MSR_MtrrFixDramEn;
51 wrmsr(SYSCFG_MSR, msr);
Stefan Reinauercadc5452010-12-18 23:29:37 +000052
Rudolf Marekb5b3b3b2011-07-02 16:36:17 +020053 /* set DRAM access to 0xa0000 */
54 msr.lo = 0x18181818;
55 msr.hi = 0x18181818;
Alexandru Gagniuc86091f92015-09-30 20:23:09 -070056 wrmsr(MTRR_FIX_16K_A0000, msr);
Rudolf Marek2c366272010-12-18 23:30:59 +000057
Rudolf Marekb5b3b3b2011-07-02 16:36:17 +020058 /* enable the extended features */
59 msr = syscfg_orig;
60 msr.lo |= SYSCFG_MSR_MtrrFixDramModEn;
61 msr.lo |= SYSCFG_MSR_MtrrFixDramEn;
62 wrmsr(SYSCFG_MSR, msr);
Stefan Reinauercadc5452010-12-18 23:29:37 +000063
Rudolf Marekb5b3b3b2011-07-02 16:36:17 +020064 enable_cache();
65 /* copy the real SMM handler */
66 memcpy((void *)SMM_BASE, &_binary_smm_start, (size_t)&_binary_smm_size);
67 wbinvd();
68 disable_cache();
Stefan Reinauercadc5452010-12-18 23:29:37 +000069
Rudolf Marekb5b3b3b2011-07-02 16:36:17 +020070 /* Restore SYSCFG and MTRR */
71 wrmsr(SYSCFG_MSR, syscfg_orig);
Alexandru Gagniuc86091f92015-09-30 20:23:09 -070072 wrmsr(MTRR_FIX_16K_A0000, mtrr_aseg_orig);
Rudolf Marekb5b3b3b2011-07-02 16:36:17 +020073 enable_cache();
Stefan Reinauercadc5452010-12-18 23:29:37 +000074
Rudolf Marekb5b3b3b2011-07-02 16:36:17 +020075 /* CPU MSR are set in CPU init */
Stefan Reinauercadc5452010-12-18 23:29:37 +000076}
Rudolf Marek2c366272010-12-18 23:30:59 +000077
78void smm_lock(void)
79{
Rudolf Marekb5b3b3b2011-07-02 16:36:17 +020080 /* We lock SMM in CPU init */
Rudolf Marek2c366272010-12-18 23:30:59 +000081}