blob: 4ee54a370fbc9b766b968af141f614a319f997db [file] [log] [blame]
Martin Roth6add44b2017-02-09 17:51:20 -08001/*
2 * This file is part of the coreboot project.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
Eric Biedermanfcd5ace2004-10-14 19:29:29 +000014#include <cpu/x86/cache.h>
15#include <cpu/x86/mtrr.h>
16#include <cpu/x86/msr.h>
17
Furquan Shaikh331ac1b2016-03-16 16:12:06 -070018/* Get first available variable MTRR.
19 * Returns var# if available, else returns -1.
20 */
21int get_free_var_mtrr(void)
22{
23 msr_t msr, maskm;
24 int vcnt;
25 int i;
26
27 /* Read MTRRCap and get vcnt - variable memory type ranges. */
28 msr = rdmsr(MTRR_CAP_MSR);
29 vcnt = msr.lo & 0xff;
30
31 /* Identify the first var mtrr which is not valid. */
32 for (i = 0; i < vcnt; i++) {
33 maskm = rdmsr(MTRR_PHYS_MASK(i));
34 if ((maskm.lo & MTRR_PHYS_MASK_VALID) == 0)
35 return i;
36 }
37
38 /* No free var mtrr. */
39 return -1;
40}
41
Kyösti Mälkki88a67f02013-12-12 12:27:53 +020042#ifdef __ROMCC__
43static
44#endif
45void set_var_mtrr(
Lee Leahy8ca9a212017-03-15 14:55:05 -070046 unsigned int reg, unsigned int base, unsigned int size,
47 unsigned int type)
Eric Biedermanfcd5ace2004-10-14 19:29:29 +000048{
49 /* Bit Bit 32-35 of MTRRphysMask should be set to 1 */
Yinghai Lu21332b82007-04-06 19:49:05 +000050 /* FIXME: It only support 4G less range */
Eric Biedermanfcd5ace2004-10-14 19:29:29 +000051 msr_t basem, maskm;
52 basem.lo = base | type;
53 basem.hi = 0;
Alexandru Gagniuc86091f92015-09-30 20:23:09 -070054 wrmsr(MTRR_PHYS_BASE(reg), basem);
55 maskm.lo = ~(size - 1) | MTRR_PHYS_MASK_VALID;
Stefan Reinauer23f49a82011-04-14 20:39:49 +000056 maskm.hi = (1 << (CONFIG_CPU_ADDR_BITS - 32)) - 1;
Alexandru Gagniuc86091f92015-09-30 20:23:09 -070057 wrmsr(MTRR_PHYS_MASK(reg), maskm);
Eric Biedermanfcd5ace2004-10-14 19:29:29 +000058}