Angel Pons | 4b42983 | 2020-04-02 23:48:50 +0200 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
Kyösti Mälkki | cb08e16 | 2013-10-15 17:19:41 +0300 | [diff] [blame] | 2 | |
Angel Pons | 1db5bc7 | 2020-01-15 00:49:03 +0100 | [diff] [blame] | 3 | /* Use simple device model for this file even in ramstage */ |
Kyösti Mälkki | cb08e16 | 2013-10-15 17:19:41 +0300 | [diff] [blame] | 4 | #define __SIMPLE_DEVICE__ |
| 5 | |
Kyösti Mälkki | a963acd | 2019-08-16 20:34:25 +0300 | [diff] [blame] | 6 | #include <arch/romstage.h> |
Kyösti Mälkki | e2e1f12 | 2019-08-09 09:34:23 +0300 | [diff] [blame] | 7 | #include <cpu/x86/mtrr.h> |
Kyösti Mälkki | 540151f | 2019-08-15 11:20:18 +0300 | [diff] [blame] | 8 | #include <cpu/x86/smm.h> |
Kyösti Mälkki | f1b58b7 | 2019-03-01 13:43:02 +0200 | [diff] [blame] | 9 | #include <device/pci_ops.h> |
Kyösti Mälkki | cb08e16 | 2013-10-15 17:19:41 +0300 | [diff] [blame] | 10 | #include <cbmem.h> |
Angel Pons | ffbb4b2 | 2020-10-15 23:25:58 +0200 | [diff] [blame] | 11 | #include <security/intel/txt/txt_platform.h> |
Angel Pons | 4b290b7 | 2020-09-24 23:38:53 +0200 | [diff] [blame] | 12 | #include <security/intel/txt/txt_register.h> |
Angel Pons | f578b6f | 2020-10-29 21:44:29 +0100 | [diff] [blame] | 13 | #include <types.h> |
Angel Pons | 4b290b7 | 2020-09-24 23:38:53 +0200 | [diff] [blame] | 14 | |
Kyösti Mälkki | cb08e16 | 2013-10-15 17:19:41 +0300 | [diff] [blame] | 15 | #include "haswell.h" |
| 16 | |
Angel Pons | 4b290b7 | 2020-09-24 23:38:53 +0200 | [diff] [blame] | 17 | static uintptr_t northbridge_get_tseg_base(void) |
| 18 | { |
| 19 | return ALIGN_DOWN(pci_read_config32(HOST_BRIDGE, TSEG), 1 * MiB); |
| 20 | } |
| 21 | |
Angel Pons | f578b6f | 2020-10-29 21:44:29 +0100 | [diff] [blame] | 22 | static uintptr_t northbridge_get_tseg_limit(void) |
Angel Pons | 4b290b7 | 2020-09-24 23:38:53 +0200 | [diff] [blame] | 23 | { |
Angel Pons | f578b6f | 2020-10-29 21:44:29 +0100 | [diff] [blame] | 24 | return ALIGN_DOWN(pci_read_config32(HOST_BRIDGE, BGSM), 1 * MiB); |
Angel Pons | 4b290b7 | 2020-09-24 23:38:53 +0200 | [diff] [blame] | 25 | } |
| 26 | |
Angel Pons | ffbb4b2 | 2020-10-15 23:25:58 +0200 | [diff] [blame] | 27 | union dpr_register txt_get_chipset_dpr(void) |
| 28 | { |
| 29 | return (union dpr_register) { .raw = pci_read_config32(HOST_BRIDGE, DPR) }; |
| 30 | } |
| 31 | |
Angel Pons | 4b290b7 | 2020-09-24 23:38:53 +0200 | [diff] [blame] | 32 | /* |
| 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 | */ |
| 37 | static uintptr_t top_of_low_usable_memory(void) |
Kyösti Mälkki | cb08e16 | 2013-10-15 17:19:41 +0300 | [diff] [blame] | 38 | { |
| 39 | /* |
Angel Pons | 4b290b7 | 2020-09-24 23:38:53 +0200 | [diff] [blame] | 40 | * 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älkki | cb08e16 | 2013-10-15 17:19:41 +0300 | [diff] [blame] | 45 | */ |
Angel Pons | 4b290b7 | 2020-09-24 23:38:53 +0200 | [diff] [blame] | 46 | uintptr_t tolum = northbridge_get_tseg_base(); |
| 47 | |
Angel Pons | ffbb4b2 | 2020-10-15 23:25:58 +0200 | [diff] [blame] | 48 | const union dpr_register dpr = txt_get_chipset_dpr(); |
Angel Pons | 4b290b7 | 2020-09-24 23:38:53 +0200 | [diff] [blame] | 49 | |
| 50 | /* Subtract DMA Protected Range size if enabled */ |
| 51 | if (dpr.epm) |
| 52 | tolum -= dpr.size * MiB; |
| 53 | |
| 54 | return tolum; |
Kyösti Mälkki | f1e3c76 | 2014-12-22 12:28:07 +0200 | [diff] [blame] | 55 | } |
| 56 | |
Elyes Haouas | 799c321 | 2022-11-09 14:00:44 +0100 | [diff] [blame] | 57 | uintptr_t cbmem_top_chipset(void) |
Kyösti Mälkki | f1e3c76 | 2014-12-22 12:28:07 +0200 | [diff] [blame] | 58 | { |
Elyes Haouas | 799c321 | 2022-11-09 14:00:44 +0100 | [diff] [blame] | 59 | return top_of_low_usable_memory(); |
Kyösti Mälkki | cb08e16 | 2013-10-15 17:19:41 +0300 | [diff] [blame] | 60 | } |
Kyösti Mälkki | 825646e | 2019-08-02 06:14:50 +0300 | [diff] [blame] | 61 | |
Kyösti Mälkki | 540151f | 2019-08-15 11:20:18 +0300 | [diff] [blame] | 62 | void smm_region(uintptr_t *start, size_t *size) |
Kyösti Mälkki | 825646e | 2019-08-02 06:14:50 +0300 | [diff] [blame] | 63 | { |
Angel Pons | 4b290b7 | 2020-09-24 23:38:53 +0200 | [diff] [blame] | 64 | *start = northbridge_get_tseg_base(); |
Angel Pons | f578b6f | 2020-10-29 21:44:29 +0100 | [diff] [blame] | 65 | *size = northbridge_get_tseg_limit(); |
| 66 | |
| 67 | *size -= *start; |
Kyösti Mälkki | 825646e | 2019-08-02 06:14:50 +0300 | [diff] [blame] | 68 | } |
Kyösti Mälkki | e2e1f12 | 2019-08-09 09:34:23 +0300 | [diff] [blame] | 69 | |
Kyösti Mälkki | 5bc641a | 2019-08-09 09:37:49 +0300 | [diff] [blame] | 70 | void fill_postcar_frame(struct postcar_frame *pcf) |
Kyösti Mälkki | e2e1f12 | 2019-08-09 09:34:23 +0300 | [diff] [blame] | 71 | { |
Kyösti Mälkki | e2e1f12 | 2019-08-09 09:34:23 +0300 | [diff] [blame] | 72 | uintptr_t top_of_ram; |
| 73 | |
Kyösti Mälkki | e2e1f12 | 2019-08-09 09:34:23 +0300 | [diff] [blame] | 74 | /* 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 Pons | 1db5bc7 | 2020-01-15 00:49:03 +0100 | [diff] [blame] | 78 | 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älkki | e2e1f12 | 2019-08-09 09:34:23 +0300 | [diff] [blame] | 80 | } |