blob: 75b9988099935c58174fd9a0cac391ed5205f0d8 [file] [log] [blame]
Kyösti Mälkki4913d8a2019-08-05 12:49:09 +03001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright 2013 Google Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <assert.h>
17#include <commonlib/helpers.h>
18#include <console/console.h>
19#include <cpu/x86/smm.h>
20#include <stage_cache.h>
21#include <types.h>
22
Kyösti Mälkki4913d8a2019-08-05 12:49:09 +030023/*
24 * Subregions within SMM
25 * +-------------------------+
26 * | IED | IED_REGION_SIZE
27 * +-------------------------+
28 * | External Stage Cache | SMM_RESERVED_SIZE
29 * +-------------------------+
30 * | code and data |
31 * | (TSEG) |
32 * +-------------------------+ TSEG
33 */
34int smm_subregion(int sub, uintptr_t *start, size_t *size)
35{
36 uintptr_t sub_base;
37 size_t sub_size;
38 const size_t ied_size = CONFIG_IED_REGION_SIZE;
39 const size_t cache_size = CONFIG_SMM_RESERVED_SIZE;
40
41 smm_region(&sub_base, &sub_size);
42
43 ASSERT(IS_ALIGNED(sub_base, sub_size));
44 ASSERT(sub_size > (cache_size + ied_size));
45
46 switch (sub) {
47 case SMM_SUBREGION_HANDLER:
48 /* Handler starts at the base of TSEG. */
49 sub_size -= ied_size;
50 sub_size -= cache_size;
51 break;
52 case SMM_SUBREGION_CACHE:
53 /* External cache is in the middle of TSEG. */
54 sub_base += sub_size - (ied_size + cache_size);
55 sub_size = cache_size;
56 break;
57 case SMM_SUBREGION_CHIPSET:
58 /* IED is at the top. */
59 sub_base += sub_size - ied_size;
60 sub_size = ied_size;
61 break;
62 default:
63 *start = 0;
64 *size = 0;
65 return -1;
66 }
67
68 *start = sub_base;
69 *size = sub_size;
70 return 0;
71}
72
Kyösti Mälkki59d57312019-08-04 21:16:34 +030073void stage_cache_external_region(void **base, size_t *size)
Kyösti Mälkki4913d8a2019-08-05 12:49:09 +030074{
75 if (smm_subregion(SMM_SUBREGION_CACHE, (uintptr_t *)base, size)) {
76 printk(BIOS_ERR, "ERROR: No cache SMM subregion.\n");
77 *base = NULL;
78 *size = 0;
79 }
80}
Kyösti Mälkki7cdb0472019-08-08 11:16:06 +030081
82void smm_list_regions(void)
83{
84 uintptr_t base;
85 size_t size;
86 int i;
87
88 smm_region(&base, &size);
89 if (!size)
90 return;
91
92 printk(BIOS_DEBUG, "SMM Memory Map\n");
93 printk(BIOS_DEBUG, "SMRAM : 0x%zx 0x%zx\n", base, size);
94
95 for (i = 0; i < SMM_SUBREGION_NUM; i++) {
96 if (smm_subregion(i, &base, &size))
97 continue;
98 printk(BIOS_DEBUG, " Subregion %d: 0x%zx 0x%zx\n", i, base, size);
99 }
100}