blob: 69bbe5872760451ddc6b491ab3f1949f8d24323a [file] [log] [blame]
Lee Leahy77ff0b12015-05-05 15:07:29 -07001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2013 Google, Inc.
Lee Leahye0918bb2016-01-29 14:28:43 -08005 * Copyright (C) 2015-2016 Intel Corp.
Lee Leahy77ff0b12015-05-05 15:07:29 -07006 *
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,
Lee Leahye0918bb2016-01-29 14:28:43 -080012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Lee Leahy77ff0b12015-05-05 15:07:29 -070013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
Lee Leahy77ff0b12015-05-05 15:07:29 -070015 */
16
Lee Leahy77ff0b12015-05-05 15:07:29 -070017#include <cbmem.h>
Kyösti Mälkkib2a5f0b2019-08-04 19:54:32 +030018#include <cpu/x86/smm.h>
Lee Leahy77ff0b12015-05-05 15:07:29 -070019#include <soc/iosf.h>
20#include <soc/smm.h>
21
Lee Leahy32471722015-04-20 15:20:28 -070022static size_t smm_region_size(void)
Lee Leahy77ff0b12015-05-05 15:07:29 -070023{
Lee Leahy32471722015-04-20 15:20:28 -070024 u32 smm_size;
25 smm_size = iosf_bunit_read(BUNIT_SMRRH) & 0xFFFF;
26 smm_size -= iosf_bunit_read(BUNIT_SMRRL) & 0xFFFF;
27 smm_size = (smm_size + 1) << 20;
28 return smm_size;
29}
30
31void smm_region(void **start, size_t *size)
32{
33 *start = (void *)((iosf_bunit_read(BUNIT_SMRRL) & 0xFFFF) << 20);
34 *size = smm_region_size();
35}
36
Aaron Durbinc43d4172015-08-05 14:51:48 -050037/*
38 * Subregions within SMM
39 * +-------------------------+ BUNIT_SMRRH
40 * | External Stage Cache | SMM_RESERVED_SIZE
41 * +-------------------------+
42 * | code and data |
43 * | (TSEG) |
44 * +-------------------------+ BUNIT_SMRRL
45 */
46int smm_subregion(int sub, void **start, size_t *size)
47{
48 uintptr_t sub_base;
49 void *sub_ptr;
50 size_t sub_size;
51 const size_t cache_size = CONFIG_SMM_RESERVED_SIZE;
52
53 smm_region(&sub_ptr, &sub_size);
54 sub_base = (uintptr_t)sub_ptr;
55
56 switch (sub) {
57 case SMM_SUBREGION_HANDLER:
58 /* Handler starts at the base of TSEG. */
59 sub_size -= cache_size;
60 break;
61 case SMM_SUBREGION_CACHE:
62 /* External cache is in the middle of TSEG. */
63 sub_base += sub_size - cache_size;
64 sub_size = cache_size;
65 break;
66 default:
67 return -1;
68 }
69
70 *start = (void *)sub_base;
71 *size = sub_size;
72
73 return 0;
74}
75
Lee Leahy77ff0b12015-05-05 15:07:29 -070076void *cbmem_top(void)
77{
Lee Leahy32471722015-04-20 15:20:28 -070078 char *smm_base;
79 size_t smm_size;
80
81 /*
82 * +-------------------------+ Top of RAM (aligned)
83 * | System Management Mode |
84 * | code and data | Length: CONFIG_TSEG_SIZE
85 * | (TSEG) |
86 * +-------------------------+ SMM base (aligned)
87 * | |
88 * | Chipset Reserved Memory | Length: Multiple of CONFIG_TSEG_SIZE
89 * | |
90 * +-------------------------+ top_of_ram (aligned)
91 * | |
92 * | CBMEM Root |
93 * | |
94 * +-------------------------+
95 * | |
96 * | FSP Reserved Memory |
97 * | |
98 * +-------------------------+
99 * | |
100 * | Various CBMEM Entries |
101 * | |
102 * +-------------------------+ top_of_stack (8 byte aligned)
103 * | |
104 * | stack (CBMEM Entry) |
105 * | |
106 * +-------------------------+
107 */
108
109 smm_region((void **)&smm_base, &smm_size);
Aaron Durbinbbbfbf22015-07-13 16:55:28 -0500110 return (void *)smm_base;
Lee Leahy77ff0b12015-05-05 15:07:29 -0700111}