blob: 47c3b102f517f99f6c76246f8f3b616b9db65b9c [file] [log] [blame]
Kyösti Mälkki7b73e8522022-11-08 04:43:41 +00001/* SPDX-License-Identifier: GPL-2.0-only */
2
3// Use simple device model for this file even in ramstage
4#define __SIMPLE_DEVICE__
5
Kyösti Mälkki7b73e8522022-11-08 04:43:41 +00006#include <arch/romstage.h>
7#include <cbmem.h>
Kyösti Mälkki560c3f52022-01-18 04:25:48 +02008#include <cpu/intel/smm_reloc.h>
Kyösti Mälkki7b73e8522022-11-08 04:43:41 +00009#include <cpu/x86/mtrr.h>
Kyösti Mälkki560c3f52022-01-18 04:25:48 +020010#include <cpu/x86/smm.h>
Elyes Haouas799c3212022-11-09 14:00:44 +010011#include <device/pci_ops.h>
Kyösti Mälkki7b73e8522022-11-08 04:43:41 +000012#include <program_loading.h>
Elyes Haouas799c3212022-11-09 14:00:44 +010013#include <stdint.h>
14
Kyösti Mälkki7b73e8522022-11-08 04:43:41 +000015#include "e7505.h"
16
Kyösti Mälkki560c3f52022-01-18 04:25:48 +020017#define HOST_BRIDGE PCI_DEV(0, 0, 0)
18
19static uintptr_t top_of_low_ram(void)
Kyösti Mälkki7b73e8522022-11-08 04:43:41 +000020{
Kyösti Mälkki7b73e8522022-11-08 04:43:41 +000021 uintptr_t tolm;
22
23 /* This is at 128 MiB boundary. */
Kyösti Mälkki560c3f52022-01-18 04:25:48 +020024 tolm = pci_read_config16(HOST_BRIDGE, TOLM) >> 11;
Kyösti Mälkki7b73e8522022-11-08 04:43:41 +000025 tolm <<= 27;
Elyes Haouas799c3212022-11-09 14:00:44 +010026 return tolm;
Kyösti Mälkki7b73e8522022-11-08 04:43:41 +000027}
28
Kyösti Mälkki560c3f52022-01-18 04:25:48 +020029size_t northbridge_get_tseg_size(void)
Kyösti Mälkki7b73e8522022-11-08 04:43:41 +000030{
Kyösti Mälkki560c3f52022-01-18 04:25:48 +020031 const uint8_t esmramc = pci_read_config8(HOST_BRIDGE, ESMRAMC);
32
33 if (!(esmramc & T_EN))
34 return 0;
35
36 switch ((esmramc & TSEG_SZ_MASK) >> 1) {
37 case 0:
38 return 128 * KiB;
39 case 1:
40 return 256 * KiB;
41 case 2:
42 return 512 * KiB;
43 case 3:
44 default:
45 return 1 * MiB;
46 }
47}
48
49uintptr_t northbridge_get_tseg_base(void)
50{
51 uintptr_t tolm = top_of_low_ram();
52
53 /* subtract TSEG size */
54 tolm -= northbridge_get_tseg_size();
55 return tolm;
56}
57
58void smm_region(uintptr_t *start, size_t *size)
59{
60 *start = northbridge_get_tseg_base();
61 *size = northbridge_get_tseg_size();
62}
63
64uintptr_t cbmem_top_chipset(void)
65{
66 return northbridge_get_tseg_base();
67}
68
69void smm_open(void)
70{
71 /* Set D_OPEN */
72 pci_write_config8(HOST_BRIDGE, SMRAMC, D_OPEN | G_SMRAME | C_BASE_SEG);
73}
74
75void smm_close(void)
76{
77 /* Clear D_OPEN */
78 pci_write_config8(HOST_BRIDGE, SMRAMC, G_SMRAME | C_BASE_SEG);
79}
80
81void smm_lock(void)
82{
83 /*
84 * LOCK the SMM memory window and enable normal SMM.
85 * After running this function, only a full reset can
86 * make the SMM registers writable again.
87 */
88 printk(BIOS_DEBUG, "Locking SMM.\n");
89
90 pci_write_config8(HOST_BRIDGE, SMRAMC, D_LCK | G_SMRAME | C_BASE_SEG);
Kyösti Mälkki7b73e8522022-11-08 04:43:41 +000091}
92
93void fill_postcar_frame(struct postcar_frame *pcf)
94{
Kyösti Mälkki7b73e8522022-11-08 04:43:41 +000095 /*
96 * Choose to NOT set ROM as WP cacheable here.
97 * Timestamps indicate the CPU this northbridge code is
98 * connected to, performs better for memcpy() and un-lzma
99 * operations when source is left as UC.
100 */
101
102 pcf->skip_common_mtrr = 1;
103
Kyösti Mälkki560c3f52022-01-18 04:25:48 +0200104 /* Cache RAM as WB from 0 -> TOLM. */
105 postcar_frame_add_mtrr(pcf, top_of_low_ram(), CACHE_TMP_RAMTOP, MTRR_TYPE_WRBACK);
Kyösti Mälkki7b73e8522022-11-08 04:43:41 +0000106}