Patrick Georgi | ac95903 | 2020-05-05 22:49:26 +0200 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ |
Mariusz Szafranski | a404133 | 2017-08-02 17:28:17 +0200 | [diff] [blame] | 2 | |
Kyösti Mälkki | 81100bf | 2019-08-16 10:37:15 +0300 | [diff] [blame] | 3 | #include <arch/romstage.h> |
Mariusz Szafranski | a404133 | 2017-08-02 17:28:17 +0200 | [diff] [blame] | 4 | #include <cbmem.h> |
| 5 | #include <assert.h> |
Kyösti Mälkki | 81100bf | 2019-08-16 10:37:15 +0300 | [diff] [blame] | 6 | #include <cpu/x86/mtrr.h> |
Kyösti Mälkki | b2a5f0b | 2019-08-04 19:54:32 +0300 | [diff] [blame] | 7 | #include <cpu/x86/smm.h> |
Mariusz Szafranski | a404133 | 2017-08-02 17:28:17 +0200 | [diff] [blame] | 8 | #include <device/device.h> |
| 9 | #include <device/pci_def.h> |
| 10 | #include <device/pci_ops.h> |
Mariusz Szafranski | a404133 | 2017-08-02 17:28:17 +0200 | [diff] [blame] | 11 | #include <soc/pci_devs.h> |
| 12 | #include <soc/systemagent.h> |
Mariusz Szafranski | a404133 | 2017-08-02 17:28:17 +0200 | [diff] [blame] | 13 | |
| 14 | /* Returns base of requested region encoded in the system agent. */ |
| 15 | static inline uintptr_t system_agent_region_base(size_t reg) |
| 16 | { |
Elyes HAOUAS | 68c851b | 2018-06-12 22:06:09 +0200 | [diff] [blame] | 17 | #if defined(__SIMPLE_DEVICE__) |
| 18 | pci_devfn_t dev = SA_DEV_ROOT; |
| 19 | #else |
Kyösti Mälkki | 28dc7dc | 2019-07-12 13:10:19 +0300 | [diff] [blame] | 20 | struct device *dev = pcidev_path_on_root(SA_DEVFN_ROOT); |
Elyes HAOUAS | 68c851b | 2018-06-12 22:06:09 +0200 | [diff] [blame] | 21 | #endif |
Mariusz Szafranski | a404133 | 2017-08-02 17:28:17 +0200 | [diff] [blame] | 22 | /* All regions concerned for have 1 MiB alignment. */ |
| 23 | return ALIGN_DOWN(pci_read_config32(dev, reg), 1 * MiB); |
| 24 | } |
| 25 | |
Mariusz Szafranski | a404133 | 2017-08-02 17:28:17 +0200 | [diff] [blame] | 26 | static inline uintptr_t smm_region_start(void) |
| 27 | { |
| 28 | return system_agent_region_base(TSEGMB); |
| 29 | } |
| 30 | |
| 31 | static inline size_t smm_region_size(void) |
| 32 | { |
| 33 | return system_agent_region_base(TOLUD) - smm_region_start(); |
| 34 | } |
| 35 | |
Kyösti Mälkki | 14222d8 | 2019-08-05 15:10:18 +0300 | [diff] [blame] | 36 | void smm_region(uintptr_t *start, size_t *size) |
Mariusz Szafranski | a404133 | 2017-08-02 17:28:17 +0200 | [diff] [blame] | 37 | { |
Kyösti Mälkki | 14222d8 | 2019-08-05 15:10:18 +0300 | [diff] [blame] | 38 | *start = smm_region_start(); |
Mariusz Szafranski | a404133 | 2017-08-02 17:28:17 +0200 | [diff] [blame] | 39 | *size = smm_region_size(); |
| 40 | } |
Kyösti Mälkki | 81100bf | 2019-08-16 10:37:15 +0300 | [diff] [blame] | 41 | |
| 42 | void fill_postcar_frame(struct postcar_frame *pcf) |
| 43 | { |
| 44 | uintptr_t top_of_ram; |
Kyösti Mälkki | 81100bf | 2019-08-16 10:37:15 +0300 | [diff] [blame] | 45 | |
| 46 | /* |
| 47 | * We need to make sure ramstage will be run cached. At this point exact |
| 48 | * location of ramstage in cbmem is not known. Instruct postcar to cache |
| 49 | * 16 megs under cbmem top which is a safe bet to cover ramstage. |
| 50 | */ |
| 51 | top_of_ram = (uintptr_t)cbmem_top(); |
| 52 | postcar_frame_add_mtrr(pcf, top_of_ram - 16 * MiB, 16 * MiB, |
| 53 | MTRR_TYPE_WRBACK); |
| 54 | |
Subrata Banik | 3eff037 | 2019-09-10 15:51:17 +0530 | [diff] [blame] | 55 | /* Cache the TSEG region */ |
| 56 | postcar_enable_tseg_cache(pcf); |
Kyösti Mälkki | 81100bf | 2019-08-16 10:37:15 +0300 | [diff] [blame] | 57 | } |