cpu/amd/family_10h-family_15h: Move CBMEM storage out of CC6 save region

The existing CBMEM TOM calculations did not account for the CC6 save region
(when enabled); this resulted in CBMEM storage being placed on top of the
CC6 save region, which resulted in corrupt CBMEM data and a boot hang.

Change-Id: I32399da0438d7b16e05192449be625f9aa675b18
Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
Reviewed-on: https://review.coreboot.org/13143
Tested-by: build bot (Jenkins)
Tested-by: Raptor Engineering Automated Test Stand <noreply@raptorengineeringinc.com>
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
This commit is contained in:
Timothy Pearson 2015-11-24 14:11:48 -06:00 committed by Martin Roth
parent 39495bae5f
commit ba2af2e21d
2 changed files with 51 additions and 1 deletions

View File

@ -18,11 +18,30 @@
#include <cpu/x86/msr.h> #include <cpu/x86/msr.h>
#include <cpu/amd/mtrr.h> #include <cpu/amd/mtrr.h>
#include <arch/io.h>
#include <device/device.h>
#include <device/pci.h>
#include <cbmem.h> #include <cbmem.h>
#include "ram_calc.h" #include "ram_calc.h"
#if !IS_ENABLED(CONFIG_LATE_CBMEM_INIT) #if !IS_ENABLED(CONFIG_LATE_CBMEM_INIT)
static inline uint8_t is_fam15h(void)
{
uint8_t fam15h = 0;
uint32_t family;
family = cpuid_eax(0x80000001);
family = ((family & 0xf00000) >> 16) | ((family & 0xf00) >> 8);
if (family >= 0x6f)
/* Family 15h or later */
fam15h = 1;
return fam15h;
}
uint64_t get_uma_memory_size(uint64_t topmem) uint64_t get_uma_memory_size(uint64_t topmem)
{ {
uint64_t uma_size = 0; uint64_t uma_size = 0;
@ -41,10 +60,40 @@ uint64_t get_uma_memory_size(uint64_t topmem)
return uma_size; return uma_size;
} }
uint64_t get_cc6_memory_size()
{
uint8_t enable_cc6;
uint64_t cc6_size = 0;
if (is_fam15h()) {
enable_cc6 = 0;
#ifdef __PRE_RAM__
if (pci_read_config32(PCI_DEV(0, 0x18, 2), 0x118) & (0x1 << 18))
enable_cc6 = 1;
#else
device_t dct_dev = dev_find_slot(0, PCI_DEVFN(0x18, 2));
if (pci_read_config32(dct_dev, 0x118) & (0x1 << 18))
enable_cc6 = 1;
#endif
if (enable_cc6) {
/* Preserve the maximum possible CC6 save region
* This needs to be kept in sync with
* amdfam10_domain_read_resources() in northbridge.c
*/
cc6_size = 0x8000000;
}
}
return cc6_size;
}
void *cbmem_top(void) void *cbmem_top(void)
{ {
uint32_t topmem = rdmsr(TOP_MEM).lo; uint32_t topmem = rdmsr(TOP_MEM).lo;
return (void *) topmem - get_uma_memory_size(topmem); return (void *) topmem - get_uma_memory_size(topmem) - get_cc6_memory_size();
} }
#endif #endif

View File

@ -17,5 +17,6 @@
#define _AMD_MODEL_10XXX_RAM_CALC_H_ #define _AMD_MODEL_10XXX_RAM_CALC_H_
uint64_t get_uma_memory_size(uint64_t topmem); uint64_t get_uma_memory_size(uint64_t topmem);
uint64_t get_cc6_memory_size(void);
#endif #endif