blob: 344dc77d076a56c987339716fd13eb70215e5a60 [file] [log] [blame]
Timothy Pearson49168802015-03-13 12:48:31 -05001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
5 * Copyright (C) 2007 Advanced Micro Devices, Inc.
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.
Timothy Pearson49168802015-03-13 12:48:31 -050015 */
16
Elyes HAOUASd2b9ec12018-10-27 09:41:02 +020017#include <arch/cpu.h>
Timothy Pearson49168802015-03-13 12:48:31 -050018#include <cpu/x86/msr.h>
19#include <cpu/amd/mtrr.h>
20
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +020021#include <device/pci_ops.h>
Timothy Pearsonba2af2e2015-11-24 14:11:48 -060022#include <device/device.h>
23#include <device/pci.h>
24
Timothy Pearson86f4ca52015-03-13 13:27:58 -050025#include <cbmem.h>
26
Timothy Pearson49168802015-03-13 12:48:31 -050027#include "ram_calc.h"
28
Timothy Pearsonba2af2e2015-11-24 14:11:48 -060029static inline uint8_t is_fam15h(void)
30{
31 uint8_t fam15h = 0;
32 uint32_t family;
33
34 family = cpuid_eax(0x80000001);
35 family = ((family & 0xf00000) >> 16) | ((family & 0xf00) >> 8);
36
37 if (family >= 0x6f)
38 /* Family 15h or later */
39 fam15h = 1;
40
41 return fam15h;
42}
43
Timothy Pearson49168802015-03-13 12:48:31 -050044uint64_t get_uma_memory_size(uint64_t topmem)
45{
46 uint64_t uma_size = 0;
47 if (IS_ENABLED(CONFIG_GFXUMA)) {
48 /* refer to UMA Size Consideration in 780 BDG. */
Timothy Pearsone24f7d32015-03-19 00:03:59 -050049 if (topmem >= 0x40000000) /* 1GB and above system memory */
Timothy Pearson49168802015-03-13 12:48:31 -050050 uma_size = 0x10000000; /* 256M recommended UMA */
51
Timothy Pearsone24f7d32015-03-19 00:03:59 -050052 else if (topmem >= 0x20000000) /* 512M - 1023M system memory */
Timothy Pearson49168802015-03-13 12:48:31 -050053 uma_size = 0x8000000; /* 128M recommended UMA */
54
Timothy Pearsone24f7d32015-03-19 00:03:59 -050055 else if (topmem >= 0x10000000) /* 256M - 511M system memory */
Timothy Pearson49168802015-03-13 12:48:31 -050056 uma_size = 0x4000000; /* 64M recommended UMA */
57 }
58
59 return uma_size;
60}
Timothy Pearson86f4ca52015-03-13 13:27:58 -050061
Timothy Pearsonba2af2e2015-11-24 14:11:48 -060062uint64_t get_cc6_memory_size()
63{
64 uint8_t enable_cc6;
65
66 uint64_t cc6_size = 0;
67
68 if (is_fam15h()) {
69 enable_cc6 = 0;
70
71#ifdef __PRE_RAM__
72 if (pci_read_config32(PCI_DEV(0, 0x18, 2), 0x118) & (0x1 << 18))
73 enable_cc6 = 1;
74#else
Kyösti Mälkkic70eed12018-05-22 02:18:00 +030075 struct device *dct_dev = pcidev_on_root(0x18, 2);
Timothy Pearsonba2af2e2015-11-24 14:11:48 -060076 if (pci_read_config32(dct_dev, 0x118) & (0x1 << 18))
77 enable_cc6 = 1;
78#endif
79
80 if (enable_cc6) {
81 /* Preserve the maximum possible CC6 save region
82 * This needs to be kept in sync with
83 * amdfam10_domain_read_resources() in northbridge.c
84 */
85 cc6_size = 0x8000000;
86 }
87 }
88
89 return cc6_size;
90}
91
Timothy Pearson86f4ca52015-03-13 13:27:58 -050092void *cbmem_top(void)
93{
94 uint32_t topmem = rdmsr(TOP_MEM).lo;
95
Timothy Pearsonba2af2e2015-11-24 14:11:48 -060096 return (void *) topmem - get_uma_memory_size(topmem) - get_cc6_memory_size();
Timothy Pearson86f4ca52015-03-13 13:27:58 -050097}