blob: ac36e259994add9f4fa61f86ebe478781b632feb [file] [log] [blame]
Angel Pons4b429832020-04-02 23:48:50 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Kyösti Mälkkicb08e162013-10-15 17:19:41 +03002
Angel Pons1db5bc72020-01-15 00:49:03 +01003/* Use simple device model for this file even in ramstage */
Kyösti Mälkkicb08e162013-10-15 17:19:41 +03004#define __SIMPLE_DEVICE__
5
Kyösti Mälkkia963acd2019-08-16 20:34:25 +03006#include <arch/romstage.h>
Kyösti Mälkkicd7a70f2019-08-17 20:51:08 +03007#include <commonlib/helpers.h>
Kyösti Mälkkie2e1f122019-08-09 09:34:23 +03008#include <cpu/x86/mtrr.h>
Kyösti Mälkki540151f2019-08-15 11:20:18 +03009#include <cpu/x86/smm.h>
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +020010#include <device/pci_ops.h>
Kyösti Mälkkicb08e162013-10-15 17:19:41 +030011#include <cbmem.h>
Angel Pons4b290b72020-09-24 23:38:53 +020012#include <security/intel/txt/txt_register.h>
13
Kyösti Mälkkicb08e162013-10-15 17:19:41 +030014#include "haswell.h"
15
Angel Pons4b290b72020-09-24 23:38:53 +020016static uintptr_t northbridge_get_tseg_base(void)
17{
18 return ALIGN_DOWN(pci_read_config32(HOST_BRIDGE, TSEG), 1 * MiB);
19}
20
21static size_t northbridge_get_tseg_size(void)
22{
23 return CONFIG_SMM_TSEG_SIZE;
24}
25
26/*
27 * Return the topmost memory address below 4 GiB available for general
28 * use, from software's view of memory. Do not confuse this with TOLUD,
29 * which applies to the DRAM as viewed by the memory controller itself.
30 */
31static uintptr_t top_of_low_usable_memory(void)
Kyösti Mälkkicb08e162013-10-15 17:19:41 +030032{
33 /*
Angel Pons4b290b72020-09-24 23:38:53 +020034 * Base of DPR is top of usable DRAM below 4 GiB. However, DPR
35 * isn't always enabled. Unlike most memory map registers, the
36 * DPR register stores top of DPR instead of its base address.
37 * Unless binary-patched, Haswell MRC.bin does not enable DPR.
38 * Top of DPR is R/O, and mirrored from TSEG base by hardware.
Kyösti Mälkkicb08e162013-10-15 17:19:41 +030039 */
Angel Pons4b290b72020-09-24 23:38:53 +020040 uintptr_t tolum = northbridge_get_tseg_base();
41
42 const union dpr_register dpr = {
43 .raw = pci_read_config32(HOST_BRIDGE, DPR),
44 };
45
46 /* Subtract DMA Protected Range size if enabled */
47 if (dpr.epm)
48 tolum -= dpr.size * MiB;
49
50 return tolum;
Kyösti Mälkkif1e3c762014-12-22 12:28:07 +020051}
52
Arthur Heymans340e4b82019-10-23 17:25:58 +020053void *cbmem_top_chipset(void)
Kyösti Mälkkif1e3c762014-12-22 12:28:07 +020054{
Angel Pons4b290b72020-09-24 23:38:53 +020055 return (void *)top_of_low_usable_memory();
Kyösti Mälkkicb08e162013-10-15 17:19:41 +030056}
Kyösti Mälkki825646e2019-08-02 06:14:50 +030057
Kyösti Mälkki540151f2019-08-15 11:20:18 +030058void smm_region(uintptr_t *start, size_t *size)
Kyösti Mälkki825646e2019-08-02 06:14:50 +030059{
Angel Pons4b290b72020-09-24 23:38:53 +020060 *start = northbridge_get_tseg_base();
61 *size = northbridge_get_tseg_size();
Kyösti Mälkki825646e2019-08-02 06:14:50 +030062}
Kyösti Mälkkie2e1f122019-08-09 09:34:23 +030063
Kyösti Mälkki5bc641a2019-08-09 09:37:49 +030064void fill_postcar_frame(struct postcar_frame *pcf)
Kyösti Mälkkie2e1f122019-08-09 09:34:23 +030065{
Kyösti Mälkkie2e1f122019-08-09 09:34:23 +030066 uintptr_t top_of_ram;
67
Kyösti Mälkkie2e1f122019-08-09 09:34:23 +030068 /* Cache at least 8 MiB below the top of ram, and at most 8 MiB
69 * above top of the ram. This satisfies MTRR alignment requirement
70 * with different TSEG size configurations.
71 */
Angel Pons1db5bc72020-01-15 00:49:03 +010072 top_of_ram = ALIGN_DOWN((uintptr_t)cbmem_top(), 8 * MiB);
73 postcar_frame_add_mtrr(pcf, top_of_ram - 8 * MiB, 16 * MiB, MTRR_TYPE_WRBACK);
Kyösti Mälkkie2e1f122019-08-09 09:34:23 +030074}