blob: df9dea5c0fa7017af48f109a6e6bfdb5c112b37a [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
23void __weak smm_region(uintptr_t *start, size_t *size)
24{
25 *start = 0;
26 *size = 0;
27}
28
29/*
30 * Subregions within SMM
31 * +-------------------------+
32 * | IED | IED_REGION_SIZE
33 * +-------------------------+
34 * | External Stage Cache | SMM_RESERVED_SIZE
35 * +-------------------------+
36 * | code and data |
37 * | (TSEG) |
38 * +-------------------------+ TSEG
39 */
40int smm_subregion(int sub, uintptr_t *start, size_t *size)
41{
42 uintptr_t sub_base;
43 size_t sub_size;
44 const size_t ied_size = CONFIG_IED_REGION_SIZE;
45 const size_t cache_size = CONFIG_SMM_RESERVED_SIZE;
46
47 smm_region(&sub_base, &sub_size);
48
49 ASSERT(IS_ALIGNED(sub_base, sub_size));
50 ASSERT(sub_size > (cache_size + ied_size));
51
52 switch (sub) {
53 case SMM_SUBREGION_HANDLER:
54 /* Handler starts at the base of TSEG. */
55 sub_size -= ied_size;
56 sub_size -= cache_size;
57 break;
58 case SMM_SUBREGION_CACHE:
59 /* External cache is in the middle of TSEG. */
60 sub_base += sub_size - (ied_size + cache_size);
61 sub_size = cache_size;
62 break;
63 case SMM_SUBREGION_CHIPSET:
64 /* IED is at the top. */
65 sub_base += sub_size - ied_size;
66 sub_size = ied_size;
67 break;
68 default:
69 *start = 0;
70 *size = 0;
71 return -1;
72 }
73
74 *start = sub_base;
75 *size = sub_size;
76 return 0;
77}
78
79void __weak stage_cache_external_region(void **base, size_t *size)
80{
81 if (smm_subregion(SMM_SUBREGION_CACHE, (uintptr_t *)base, size)) {
82 printk(BIOS_ERR, "ERROR: No cache SMM subregion.\n");
83 *base = NULL;
84 *size = 0;
85 }
86}