blob: 6b75caa86126a8681b023c582b7539fc307f8d25 [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älkkie2e1f122019-08-09 09:34:23 +03007#include <cpu/x86/mtrr.h>
Kyösti Mälkki540151f2019-08-15 11:20:18 +03008#include <cpu/x86/smm.h>
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +02009#include <device/pci_ops.h>
Kyösti Mälkkicb08e162013-10-15 17:19:41 +030010#include <cbmem.h>
Angel Ponsffbb4b22020-10-15 23:25:58 +020011#include <security/intel/txt/txt_platform.h>
Angel Pons4b290b72020-09-24 23:38:53 +020012#include <security/intel/txt/txt_register.h>
Angel Ponsf578b6f2020-10-29 21:44:29 +010013#include <types.h>
Angel Pons4b290b72020-09-24 23:38:53 +020014
Kyösti Mälkkicb08e162013-10-15 17:19:41 +030015#include "haswell.h"
16
Angel Pons4b290b72020-09-24 23:38:53 +020017static uintptr_t northbridge_get_tseg_base(void)
18{
19 return ALIGN_DOWN(pci_read_config32(HOST_BRIDGE, TSEG), 1 * MiB);
20}
21
Angel Ponsf578b6f2020-10-29 21:44:29 +010022static uintptr_t northbridge_get_tseg_limit(void)
Angel Pons4b290b72020-09-24 23:38:53 +020023{
Angel Ponsf578b6f2020-10-29 21:44:29 +010024 return ALIGN_DOWN(pci_read_config32(HOST_BRIDGE, BGSM), 1 * MiB);
Angel Pons4b290b72020-09-24 23:38:53 +020025}
26
Angel Ponsffbb4b22020-10-15 23:25:58 +020027union dpr_register txt_get_chipset_dpr(void)
28{
29 return (union dpr_register) { .raw = pci_read_config32(HOST_BRIDGE, DPR) };
30}
31
Angel Pons4b290b72020-09-24 23:38:53 +020032/*
33 * Return the topmost memory address below 4 GiB available for general
34 * use, from software's view of memory. Do not confuse this with TOLUD,
35 * which applies to the DRAM as viewed by the memory controller itself.
36 */
37static uintptr_t top_of_low_usable_memory(void)
Kyösti Mälkkicb08e162013-10-15 17:19:41 +030038{
39 /*
Angel Pons4b290b72020-09-24 23:38:53 +020040 * Base of DPR is top of usable DRAM below 4 GiB. However, DPR
41 * isn't always enabled. Unlike most memory map registers, the
42 * DPR register stores top of DPR instead of its base address.
43 * Unless binary-patched, Haswell MRC.bin does not enable DPR.
44 * Top of DPR is R/O, and mirrored from TSEG base by hardware.
Kyösti Mälkkicb08e162013-10-15 17:19:41 +030045 */
Angel Pons4b290b72020-09-24 23:38:53 +020046 uintptr_t tolum = northbridge_get_tseg_base();
47
Angel Ponsffbb4b22020-10-15 23:25:58 +020048 const union dpr_register dpr = txt_get_chipset_dpr();
Angel Pons4b290b72020-09-24 23:38:53 +020049
50 /* Subtract DMA Protected Range size if enabled */
51 if (dpr.epm)
52 tolum -= dpr.size * MiB;
53
54 return tolum;
Kyösti Mälkkif1e3c762014-12-22 12:28:07 +020055}
56
Elyes Haouas799c3212022-11-09 14:00:44 +010057uintptr_t cbmem_top_chipset(void)
Kyösti Mälkkif1e3c762014-12-22 12:28:07 +020058{
Elyes Haouas799c3212022-11-09 14:00:44 +010059 return top_of_low_usable_memory();
Kyösti Mälkkicb08e162013-10-15 17:19:41 +030060}
Kyösti Mälkki825646e2019-08-02 06:14:50 +030061
Kyösti Mälkki540151f2019-08-15 11:20:18 +030062void smm_region(uintptr_t *start, size_t *size)
Kyösti Mälkki825646e2019-08-02 06:14:50 +030063{
Angel Pons4b290b72020-09-24 23:38:53 +020064 *start = northbridge_get_tseg_base();
Angel Ponsf578b6f2020-10-29 21:44:29 +010065 *size = northbridge_get_tseg_limit();
66
67 *size -= *start;
Kyösti Mälkki825646e2019-08-02 06:14:50 +030068}
Kyösti Mälkkie2e1f122019-08-09 09:34:23 +030069
Kyösti Mälkki5bc641a2019-08-09 09:37:49 +030070void fill_postcar_frame(struct postcar_frame *pcf)
Kyösti Mälkkie2e1f122019-08-09 09:34:23 +030071{
Kyösti Mälkkie2e1f122019-08-09 09:34:23 +030072 uintptr_t top_of_ram;
73
Kyösti Mälkkie2e1f122019-08-09 09:34:23 +030074 /* Cache at least 8 MiB below the top of ram, and at most 8 MiB
75 * above top of the ram. This satisfies MTRR alignment requirement
76 * with different TSEG size configurations.
77 */
Angel Pons1db5bc72020-01-15 00:49:03 +010078 top_of_ram = ALIGN_DOWN((uintptr_t)cbmem_top(), 8 * MiB);
79 postcar_frame_add_mtrr(pcf, top_of_ram - 8 * MiB, 16 * MiB, MTRR_TYPE_WRBACK);
Kyösti Mälkkie2e1f122019-08-09 09:34:23 +030080}