blob: f6aecd0557e5769e9947ac7229e6b08a65bdab79 [file] [log] [blame]
Angel Ponsf23ae0b2020-04-02 23:48:12 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Kyösti Mälkki4913d8a2019-08-05 12:49:09 +03002
3#include <assert.h>
4#include <commonlib/helpers.h>
5#include <console/console.h>
6#include <cpu/x86/smm.h>
7#include <stage_cache.h>
8#include <types.h>
Jacob Garber06f2fcc2019-11-04 09:35:15 -07009#include <inttypes.h>
Kyösti Mälkki4913d8a2019-08-05 12:49:09 +030010
Kyösti Mälkki4913d8a2019-08-05 12:49:09 +030011/*
12 * Subregions within SMM
13 * +-------------------------+
14 * | IED | IED_REGION_SIZE
15 * +-------------------------+
16 * | External Stage Cache | SMM_RESERVED_SIZE
17 * +-------------------------+
18 * | code and data |
19 * | (TSEG) |
20 * +-------------------------+ TSEG
21 */
22int smm_subregion(int sub, uintptr_t *start, size_t *size)
23{
24 uintptr_t sub_base;
25 size_t sub_size;
26 const size_t ied_size = CONFIG_IED_REGION_SIZE;
27 const size_t cache_size = CONFIG_SMM_RESERVED_SIZE;
28
29 smm_region(&sub_base, &sub_size);
30
31 ASSERT(IS_ALIGNED(sub_base, sub_size));
32 ASSERT(sub_size > (cache_size + ied_size));
33
34 switch (sub) {
35 case SMM_SUBREGION_HANDLER:
36 /* Handler starts at the base of TSEG. */
37 sub_size -= ied_size;
38 sub_size -= cache_size;
39 break;
40 case SMM_SUBREGION_CACHE:
41 /* External cache is in the middle of TSEG. */
42 sub_base += sub_size - (ied_size + cache_size);
43 sub_size = cache_size;
44 break;
45 case SMM_SUBREGION_CHIPSET:
46 /* IED is at the top. */
47 sub_base += sub_size - ied_size;
48 sub_size = ied_size;
49 break;
50 default:
51 *start = 0;
52 *size = 0;
53 return -1;
54 }
55
56 *start = sub_base;
57 *size = sub_size;
58 return 0;
59}
60
Kyösti Mälkki59d57312019-08-04 21:16:34 +030061void stage_cache_external_region(void **base, size_t *size)
Kyösti Mälkki4913d8a2019-08-05 12:49:09 +030062{
63 if (smm_subregion(SMM_SUBREGION_CACHE, (uintptr_t *)base, size)) {
Julius Wernere9665952022-01-21 17:06:20 -080064 printk(BIOS_ERR, "No cache SMM subregion.\n");
Kyösti Mälkki4913d8a2019-08-05 12:49:09 +030065 *base = NULL;
66 *size = 0;
67 }
68}
Kyösti Mälkki7cdb0472019-08-08 11:16:06 +030069
70void smm_list_regions(void)
71{
72 uintptr_t base;
73 size_t size;
74 int i;
75
76 smm_region(&base, &size);
77 if (!size)
78 return;
79
80 printk(BIOS_DEBUG, "SMM Memory Map\n");
Jacob Garber06f2fcc2019-11-04 09:35:15 -070081 printk(BIOS_DEBUG, "SMRAM : 0x%" PRIxPTR " 0x%zx\n", base, size);
Kyösti Mälkki7cdb0472019-08-08 11:16:06 +030082
83 for (i = 0; i < SMM_SUBREGION_NUM; i++) {
84 if (smm_subregion(i, &base, &size))
85 continue;
Jacob Garber06f2fcc2019-11-04 09:35:15 -070086 printk(BIOS_DEBUG, " Subregion %d: 0x%" PRIxPTR " 0x%zx\n", i, base, size);
Kyösti Mälkki7cdb0472019-08-08 11:16:06 +030087 }
88}