blob: e6bb51fd25adce75438dba461eed2caa34c87694 [file] [log] [blame]
Lee Leahyfba78bf2016-03-03 16:48:22 -08001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2013 Google Inc.
5 * Copyright (C) 2015-2016 Intel Corp.
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.
15 */
16
17#include <console/console.h>
18#include <cpu/x86/msr.h>
19#include <cpu/x86/mtrr.h>
20#include <soc/intel/common/util.h>
21#include <soc/pci_devs.h>
Lee Leahy01728bb2016-07-20 08:58:58 -070022#include <soc/reg_access.h>
Lee Leahyfba78bf2016-03-03 16:48:22 -080023
Lee Leahyfba78bf2016-03-03 16:48:22 -080024asmlinkage void *soc_set_mtrrs(void *top_of_stack)
25{
26 union {
27 uint32_t u32[2];
28 uint64_t u64;
29 msr_t msr;
30 } data;
31 uint32_t mtrr_count;
32 uint32_t *mtrr_data;
33 uint32_t mtrr_reg;
34
35 /*
36 * The stack contents are initialized in src/soc/intel/common/stack.c
37 * to be the following:
38 *
39 * *
40 * *
41 * *
42 * +36: MTRR mask 1 63:32
43 * +32: MTRR mask 1 31:0
44 * +28: MTRR base 1 63:32
45 * +24: MTRR base 1 31:0
46 * +20: MTRR mask 0 63:32
47 * +16: MTRR mask 0 31:0
48 * +12: MTRR base 0 63:32
49 * +8: MTRR base 0 31:0
50 * +4: Number of MTRRs to setup (described above)
51 * top_of_stack --> +0: Number of variable MTRRs to clear
52 *
53 * This routine:
54 * * Clears all of the variable MTRRs
55 * * Initializes the variable MTRRs with the data passed in
56 * * Returns the new top of stack after removing all of the
57 * data passed in.
58 */
59
60 /* Clear all of the variable MTRRs (base and mask). */
61 mtrr_reg = MTRR_PHYS_BASE(0);
62 mtrr_data = top_of_stack;
63 mtrr_count = (*mtrr_data++) * 2;
64 data.u64 = 0;
65 while (mtrr_count-- > 0)
Lee Leahyae738ac2016-07-24 08:03:37 -070066 soc_msr_write(mtrr_reg++, data.msr);
Lee Leahyfba78bf2016-03-03 16:48:22 -080067
68 /* Setup the specified variable MTRRs */
69 mtrr_reg = MTRR_PHYS_BASE(0);
70 mtrr_count = *mtrr_data++;
71 while (mtrr_count-- > 0) {
72 data.u32[0] = *mtrr_data++;
73 data.u32[1] = *mtrr_data++;
Lee Leahyae738ac2016-07-24 08:03:37 -070074 soc_msr_write(mtrr_reg++, data.msr); /* Base */
Lee Leahyfba78bf2016-03-03 16:48:22 -080075 data.u32[0] = *mtrr_data++;
76 data.u32[1] = *mtrr_data++;
Lee Leahyae738ac2016-07-24 08:03:37 -070077 soc_msr_write(mtrr_reg++, data.msr); /* Mask */
Lee Leahyfba78bf2016-03-03 16:48:22 -080078 }
79
80 /* Remove setup_stack_and_mtrrs data and return the new top_of_stack */
81 top_of_stack = mtrr_data;
82 return top_of_stack;
83}
84
85asmlinkage void soc_enable_mtrrs(void)
86{
87 union {
88 uint32_t u32[2];
89 uint64_t u64;
90 msr_t msr;
91 } data;
92
93 /* Enable MTRR. */
Lee Leahyae738ac2016-07-24 08:03:37 -070094 data.msr = soc_msr_read(MTRR_DEF_TYPE_MSR);
Lee Leahyfba78bf2016-03-03 16:48:22 -080095 data.u32[0] |= MTRR_DEF_TYPE_EN;
Lee Leahyae738ac2016-07-24 08:03:37 -070096 soc_msr_write(MTRR_DEF_TYPE_MSR, data.msr);
Lee Leahyfba78bf2016-03-03 16:48:22 -080097}