2017-02-10 02:51:20 +01:00
|
|
|
/*
|
|
|
|
* This file is part of the coreboot project.
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
2019-08-07 05:24:15 +02:00
|
|
|
#include <cpu/cpu.h>
|
2004-10-14 21:29:29 +02:00
|
|
|
#include <cpu/x86/cache.h>
|
|
|
|
#include <cpu/x86/mtrr.h>
|
|
|
|
#include <cpu/x86/msr.h>
|
|
|
|
|
2016-03-17 00:12:06 +01:00
|
|
|
/* Get first available variable MTRR.
|
|
|
|
* Returns var# if available, else returns -1.
|
|
|
|
*/
|
|
|
|
int get_free_var_mtrr(void)
|
|
|
|
{
|
2018-11-13 19:28:07 +01:00
|
|
|
msr_t maskm;
|
2016-03-17 00:12:06 +01:00
|
|
|
int vcnt;
|
|
|
|
int i;
|
|
|
|
|
2018-11-13 19:28:07 +01:00
|
|
|
vcnt = get_var_mtrr_count();
|
2016-03-17 00:12:06 +01:00
|
|
|
|
|
|
|
/* Identify the first var mtrr which is not valid. */
|
|
|
|
for (i = 0; i < vcnt; i++) {
|
|
|
|
maskm = rdmsr(MTRR_PHYS_MASK(i));
|
|
|
|
if ((maskm.lo & MTRR_PHYS_MASK_VALID) == 0)
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* No free var mtrr. */
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2013-12-12 11:27:53 +01:00
|
|
|
void set_var_mtrr(
|
2017-03-15 22:55:05 +01:00
|
|
|
unsigned int reg, unsigned int base, unsigned int size,
|
|
|
|
unsigned int type)
|
2004-10-14 21:29:29 +02:00
|
|
|
{
|
|
|
|
/* Bit Bit 32-35 of MTRRphysMask should be set to 1 */
|
2007-04-06 21:49:05 +02:00
|
|
|
/* FIXME: It only support 4G less range */
|
2004-10-14 21:29:29 +02:00
|
|
|
msr_t basem, maskm;
|
|
|
|
basem.lo = base | type;
|
|
|
|
basem.hi = 0;
|
2015-10-01 05:23:09 +02:00
|
|
|
wrmsr(MTRR_PHYS_BASE(reg), basem);
|
|
|
|
maskm.lo = ~(size - 1) | MTRR_PHYS_MASK_VALID;
|
2019-08-07 05:24:15 +02:00
|
|
|
maskm.hi = (1 << (cpu_phys_address_size() - 32)) - 1;
|
2015-10-01 05:23:09 +02:00
|
|
|
wrmsr(MTRR_PHYS_MASK(reg), maskm);
|
2004-10-14 21:29:29 +02:00
|
|
|
}
|