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