Lee Leahy | b000513 | 2015-05-12 18:19:47 -0700 | [diff] [blame] | 1 | /* |
| 2 | * This file is part of the coreboot project. |
| 3 | * |
| 4 | * Copyright (C) 2014 Google Inc. |
Lee Leahy | e0918bb | 2016-01-29 14:28:43 -0800 | [diff] [blame] | 5 | * Copyright (C) 2015-2016 Intel Corporation. |
Lee Leahy | b000513 | 2015-05-12 18:19:47 -0700 | [diff] [blame] | 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. |
Lee Leahy | b000513 | 2015-05-12 18:19:47 -0700 | [diff] [blame] | 15 | */ |
| 16 | |
| 17 | #include <arch/io.h> |
| 18 | #include <cbmem.h> |
Rizwan Qureshi | 188e370 | 2015-07-23 17:40:32 +0530 | [diff] [blame] | 19 | #include <chip.h> |
Rizwan Qureshi | 188e370 | 2015-07-23 17:40:32 +0530 | [diff] [blame] | 20 | #include <device/device.h> |
Lee Leahy | b000513 | 2015-05-12 18:19:47 -0700 | [diff] [blame] | 21 | #include <device/pci.h> |
Rizwan Qureshi | 188e370 | 2015-07-23 17:40:32 +0530 | [diff] [blame] | 22 | #include <soc/msr.h> |
Lee Leahy | b000513 | 2015-05-12 18:19:47 -0700 | [diff] [blame] | 23 | #include <soc/pci_devs.h> |
Lee Leahy | 1d14b3e | 2015-05-12 18:23:27 -0700 | [diff] [blame] | 24 | #include <soc/smm.h> |
Lee Leahy | b000513 | 2015-05-12 18:19:47 -0700 | [diff] [blame] | 25 | #include <soc/systemagent.h> |
Aaron Durbin | a0429b6 | 2015-08-05 14:33:37 -0500 | [diff] [blame] | 26 | #include <stdlib.h> |
Lee Leahy | b000513 | 2015-05-12 18:19:47 -0700 | [diff] [blame] | 27 | |
Lee Leahy | e0918bb | 2016-01-29 14:28:43 -0800 | [diff] [blame] | 28 | size_t mmap_region_granularity(void) |
Lee Leahy | 1d14b3e | 2015-05-12 18:23:27 -0700 | [diff] [blame] | 29 | { |
| 30 | if (IS_ENABLED(CONFIG_HAVE_SMI_HANDLER)) |
| 31 | /* Align to TSEG size when SMM is in use */ |
| 32 | if (CONFIG_SMM_TSEG_SIZE != 0) |
| 33 | return CONFIG_SMM_TSEG_SIZE; |
| 34 | |
| 35 | /* Make it 8MiB by default. */ |
Aaron Durbin | a0429b6 | 2015-08-05 14:33:37 -0500 | [diff] [blame] | 36 | return 8*MiB; |
Lee Leahy | 1d14b3e | 2015-05-12 18:23:27 -0700 | [diff] [blame] | 37 | } |
| 38 | |
Aaron Durbin | a0429b6 | 2015-08-05 14:33:37 -0500 | [diff] [blame] | 39 | /* Returns base of requested region encoded in the system agent. */ |
| 40 | static inline uintptr_t system_agent_region_base(size_t reg) |
Lee Leahy | b000513 | 2015-05-12 18:19:47 -0700 | [diff] [blame] | 41 | { |
Aaron Durbin | a0429b6 | 2015-08-05 14:33:37 -0500 | [diff] [blame] | 42 | /* All regions concerned for have 1 MiB alignment. */ |
| 43 | return ALIGN_DOWN(pci_read_config32(SA_DEV_ROOT, reg), 1*MiB); |
| 44 | } |
| 45 | |
| 46 | static inline uintptr_t smm_region_start(void) |
| 47 | { |
| 48 | return system_agent_region_base(TSEG); |
| 49 | } |
| 50 | |
| 51 | static inline size_t smm_region_size(void) |
| 52 | { |
| 53 | return system_agent_region_base(BGSM) - smm_region_start(); |
Lee Leahy | 1d14b3e | 2015-05-12 18:23:27 -0700 | [diff] [blame] | 54 | } |
Lee Leahy | b000513 | 2015-05-12 18:19:47 -0700 | [diff] [blame] | 55 | |
Lee Leahy | 1d14b3e | 2015-05-12 18:23:27 -0700 | [diff] [blame] | 56 | void smm_region(void **start, size_t *size) |
| 57 | { |
Aaron Durbin | a0429b6 | 2015-08-05 14:33:37 -0500 | [diff] [blame] | 58 | *start = (void *)smm_region_start(); |
| 59 | *size = smm_region_size(); |
Lee Leahy | b000513 | 2015-05-12 18:19:47 -0700 | [diff] [blame] | 60 | } |
| 61 | |
Aaron Durbin | c43d417 | 2015-08-05 14:51:48 -0500 | [diff] [blame] | 62 | /* |
| 63 | * Subregions within SMM |
| 64 | * +-------------------------+ BGSM |
| 65 | * | IED | IED_REGION_SIZE |
| 66 | * +-------------------------+ |
| 67 | * | External Stage Cache | SMM_RESERVED_SIZE |
| 68 | * +-------------------------+ |
| 69 | * | code and data | |
| 70 | * | (TSEG) | |
| 71 | * +-------------------------+ TSEG |
| 72 | */ |
| 73 | int smm_subregion(int sub, void **start, size_t *size) |
| 74 | { |
| 75 | uintptr_t sub_base; |
| 76 | size_t sub_size; |
| 77 | const size_t ied_size = CONFIG_IED_REGION_SIZE; |
| 78 | const size_t cache_size = CONFIG_SMM_RESERVED_SIZE; |
| 79 | |
| 80 | sub_base = smm_region_start(); |
| 81 | sub_size = smm_region_size(); |
| 82 | |
| 83 | switch (sub) { |
| 84 | case SMM_SUBREGION_HANDLER: |
| 85 | /* Handler starts at the base of TSEG. */ |
| 86 | sub_size -= ied_size; |
| 87 | sub_size -= cache_size; |
| 88 | break; |
| 89 | case SMM_SUBREGION_CACHE: |
| 90 | /* External cache is in the middle of TSEG. */ |
| 91 | sub_base += sub_size - (ied_size + cache_size); |
| 92 | sub_size = cache_size; |
| 93 | break; |
| 94 | case SMM_SUBREGION_CHIPSET: |
| 95 | /* IED is at the top. */ |
| 96 | sub_base += sub_size - ied_size; |
| 97 | sub_size = ied_size; |
| 98 | break; |
| 99 | default: |
| 100 | return -1; |
| 101 | } |
| 102 | |
| 103 | *start = (void *)sub_base; |
| 104 | *size = sub_size; |
| 105 | |
| 106 | return 0; |
| 107 | } |
| 108 | |
Rizwan Qureshi | 188e370 | 2015-07-23 17:40:32 +0530 | [diff] [blame] | 109 | /* |
| 110 | * Host Memory Map: |
| 111 | * |
| 112 | * +--------------------------+ TOUUD |
| 113 | * | | |
| 114 | * +--------------------------+ 4GiB |
| 115 | * | PCI Address Space | |
| 116 | * +--------------------------+ TOLUD (also maps into MC address space) |
| 117 | * | iGD | |
| 118 | * +--------------------------+ BDSM |
| 119 | * | GTT | |
| 120 | * +--------------------------+ BGSM |
| 121 | * | TSEG | |
| 122 | * +--------------------------+ TSEGMB |
| 123 | * | DMA Protected Region | |
| 124 | * +--------------------------+ DPR |
| 125 | * | PRM (C6DRAM/SGX) | |
| 126 | * +--------------------------+ PRMRR |
| 127 | * | Trace Memory | |
| 128 | * +--------------------------+ top_of_ram |
| 129 | * | Reserved - FSP/CBMEM | |
| 130 | * +--------------------------+ TOLUM |
| 131 | * | Usage DRAM | |
| 132 | * +--------------------------+ 0 |
| 133 | * |
| 134 | * Some of the base registers above can be equal making the size of those |
| 135 | * regions 0. The reason is because the memory controller internally subtracts |
| 136 | * the base registers from each other to determine sizes of the regions. In |
| 137 | * other words, the memory map is in a fixed order no matter what. |
| 138 | */ |
| 139 | |
| 140 | u32 top_of_32bit_ram(void) |
| 141 | { |
| 142 | msr_t prmrr_base; |
| 143 | u32 top_of_ram; |
| 144 | const struct device *dev; |
| 145 | const struct soc_intel_skylake_config *config; |
| 146 | |
| 147 | /* |
| 148 | * Check if Tseg has been initialized, we will use this as a flag |
| 149 | * to check if the MRC is done, and only then continue to read the |
| 150 | * PRMMR_BASE MSR. The system hangs if PRMRR_BASE MSR is read before |
| 151 | * PRMRR_MASK MSR lock bit is set. |
| 152 | */ |
Naresh G Solanki | 721d1b3 | 2016-11-16 21:32:04 +0530 | [diff] [blame] | 153 | top_of_ram = smm_region_start(); |
| 154 | if (top_of_ram == 0) |
Rizwan Qureshi | 188e370 | 2015-07-23 17:40:32 +0530 | [diff] [blame] | 155 | return 0; |
| 156 | |
| 157 | dev = dev_find_slot(0, PCI_DEVFN(SA_DEV_SLOT_ROOT, 0)); |
| 158 | config = dev->chip_info; |
| 159 | |
| 160 | /* |
| 161 | * On Skylake, cbmem_top is offset down from PRMRR_BASE by reserved |
| 162 | * memory (128MiB) for CPU trace if enabled, then reserved memory (4KB) |
| 163 | * for PTT if enabled. PTT is in fact not used on Skylake platforms. |
| 164 | * Refer to Fsp Integration Guide for the memory mapping layout. |
| 165 | */ |
| 166 | prmrr_base = rdmsr(UNCORE_PRMRR_PHYS_BASE_MSR); |
Naresh G Solanki | 721d1b3 | 2016-11-16 21:32:04 +0530 | [diff] [blame] | 167 | if (prmrr_base.lo) |
| 168 | top_of_ram = prmrr_base.lo; |
Rizwan Qureshi | 188e370 | 2015-07-23 17:40:32 +0530 | [diff] [blame] | 169 | |
| 170 | if (config->ProbelessTrace) |
| 171 | top_of_ram -= TRACE_MEMORY_SIZE; |
| 172 | |
| 173 | return top_of_ram; |
| 174 | } |
| 175 | |
Lee Leahy | b000513 | 2015-05-12 18:19:47 -0700 | [diff] [blame] | 176 | void *cbmem_top(void) |
| 177 | { |
Lee Leahy | 1d14b3e | 2015-05-12 18:23:27 -0700 | [diff] [blame] | 178 | /* |
| 179 | * +-------------------------+ Top of RAM (aligned) |
| 180 | * | System Management Mode | |
| 181 | * | code and data | Length: CONFIG_TSEG_SIZE |
| 182 | * | (TSEG) | |
| 183 | * +-------------------------+ SMM base (aligned) |
| 184 | * | | |
Rizwan Qureshi | 188e370 | 2015-07-23 17:40:32 +0530 | [diff] [blame] | 185 | * | Chipset Reserved Memory | |
Lee Leahy | 1d14b3e | 2015-05-12 18:23:27 -0700 | [diff] [blame] | 186 | * | | |
| 187 | * +-------------------------+ top_of_ram (aligned) |
| 188 | * | | |
| 189 | * | CBMEM Root | |
| 190 | * | | |
| 191 | * +-------------------------+ |
| 192 | * | | |
| 193 | * | FSP Reserved Memory | |
| 194 | * | | |
| 195 | * +-------------------------+ |
| 196 | * | | |
| 197 | * | Various CBMEM Entries | |
| 198 | * | | |
| 199 | * +-------------------------+ top_of_stack (8 byte aligned) |
| 200 | * | | |
| 201 | * | stack (CBMEM Entry) | |
| 202 | * | | |
| 203 | * +-------------------------+ |
| 204 | */ |
Rizwan Qureshi | 188e370 | 2015-07-23 17:40:32 +0530 | [diff] [blame] | 205 | return (void *)top_of_32bit_ram(); |
Lee Leahy | b000513 | 2015-05-12 18:19:47 -0700 | [diff] [blame] | 206 | } |