xref: /aosp_15_r20/external/coreboot/src/soc/intel/common/block/systemagent/systemagent_early.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #define __SIMPLE_DEVICE__
4 
5 #include <assert.h>
6 #include <device/mmio.h>
7 #include <device/pci_ops.h>
8 #include <device/device.h>
9 #include <device/pci.h>
10 #include <intelblocks/systemagent.h>
11 #include <security/intel/txt/txt_platform.h>
12 #include <security/intel/txt/txt_register.h>
13 #include <soc/iomap.h>
14 #include <soc/pci_devs.h>
15 #include <soc/systemagent.h>
16 
17 #include "systemagent_def.h"
18 
bootblock_systemagent_early_init(void)19 void bootblock_systemagent_early_init(void)
20 {
21 	uint32_t reg;
22 	uint8_t pciexbar_length;
23 
24 	/*
25 	 * The PCIEXBAR is assumed to live in the memory mapped IO space under
26 	 * 4GiB.
27 	 */
28 	reg = 0;
29 	pci_io_write_config32(SA_DEV_ROOT, PCIEXBAR + 4, reg);
30 
31 	/* Get PCI Express Region Length */
32 	switch (CONFIG_ECAM_MMCONF_BUS_NUMBER) {
33 	case 256:
34 		pciexbar_length = PCIEXBAR_LENGTH_256MB;
35 		break;
36 	case 128:
37 		pciexbar_length = PCIEXBAR_LENGTH_128MB;
38 		break;
39 	case 64:
40 		pciexbar_length = PCIEXBAR_LENGTH_64MB;
41 		break;
42 	default:
43 		dead_code();
44 	}
45 	reg = CONFIG_ECAM_MMCONF_BASE_ADDRESS | (pciexbar_length << 1)
46 				| PCIEXBAR_PCIEXBAREN;
47 	pci_io_write_config32(SA_DEV_ROOT, PCIEXBAR, reg);
48 
49 	/*
50 	 * TSEG defines the base of SMM range. BIOS determines the base
51 	 * of TSEG memory which must be at or below Graphics base of GTT
52 	 * Stolen memory, hence its better to clear TSEG register early
53 	 * to avoid power on default non-zero value (if any).
54 	 */
55 	pci_write_config32(SA_DEV_ROOT, TSEG, 0);
56 }
57 
sa_set_pci_bar(const struct sa_mmio_descriptor * fixed_set_resources,size_t count)58 void sa_set_pci_bar(const struct sa_mmio_descriptor *fixed_set_resources,
59 		size_t count)
60 {
61 	int i;
62 
63 	for (i = 0; i < count; i++) {
64 		uint64_t base;
65 		unsigned int index;
66 
67 		index = fixed_set_resources[i].index;
68 		/* Check if PCI BAR already enabled */
69 		base = pci_read_config32(SA_DEV_ROOT, index);
70 
71 		/* If enabled don't program it. */
72 		if (base & PCIEXBAR_PCIEXBAREN)
73 			return;
74 
75 		base = fixed_set_resources[i].base;
76 		if (base >> 32)
77 			pci_write_config32(SA_DEV_ROOT, index + 4, base >> 32);
78 		pci_write_config32(SA_DEV_ROOT, index,
79 			(base & 0xffffffff) | PCIEXBAR_PCIEXBAREN);
80 	}
81 }
82 
83 /*
84  * There are special BARs that actually are programmed in the MCHBAR. These
85  * Intel special features, but they do consume resources that need to be
86  * accounted for.
87  */
sa_set_mch_bar(const struct sa_mmio_descriptor * fixed_set_resources,size_t count)88 void sa_set_mch_bar(const struct sa_mmio_descriptor *fixed_set_resources,
89 		size_t count)
90 {
91 	int i;
92 
93 	for (i = 0; i < count; i++) {
94 		uint64_t base;
95 		unsigned int index;
96 
97 		base = fixed_set_resources[i].base;
98 		index = fixed_set_resources[i].index;
99 		if (base >> 32)
100 			write32p((uintptr_t)(MCH_BASE_ADDRESS + index + 4), base >> 32);
101 		write32p((uintptr_t)(MCH_BASE_ADDRESS + index),
102 			(base & 0xffffffff) | PCIEXBAR_PCIEXBAREN);
103 	}
104 }
105 
enable_pam_region(void)106 void enable_pam_region(void)
107 {
108 	/* All read and writes in this region are serviced by DRAM */
109 	pci_write_config8(SA_DEV_ROOT, PAM0, 0x30);
110 	pci_write_config8(SA_DEV_ROOT, PAM1, 0x33);
111 	pci_write_config8(SA_DEV_ROOT, PAM2, 0x33);
112 	pci_write_config8(SA_DEV_ROOT, PAM3, 0x33);
113 	pci_write_config8(SA_DEV_ROOT, PAM4, 0x33);
114 	pci_write_config8(SA_DEV_ROOT, PAM5, 0x33);
115 	pci_write_config8(SA_DEV_ROOT, PAM6, 0x33);
116 }
117 
enable_bios_reset_cpl(void)118 void enable_bios_reset_cpl(void)
119 {
120 	u8 bios_reset_cpl;
121 
122 	/*
123 	 * Set bits 0+1 of BIOS_RESET_CPL to indicate to the CPU
124 	 * that BIOS has initialized memory and power management
125 	 */
126 	bios_reset_cpl = MCHBAR8(BIOS_RESET_CPL);
127 	bios_reset_cpl |= 3;
128 	MCHBAR8(BIOS_RESET_CPL) = bios_reset_cpl;
129 }
130 
sa_get_tolud_base(void)131 uintptr_t sa_get_tolud_base(void)
132 {
133 	/* All regions concerned for have 1 MiB alignment. */
134 	return ALIGN_DOWN(pci_read_config32(SA_DEV_ROOT, TOLUD), 1*MiB);
135 }
136 
sa_get_gsm_base(void)137 uintptr_t sa_get_gsm_base(void)
138 {
139 	/* All regions concerned for have 1 MiB alignment. */
140 	return ALIGN_DOWN(pci_read_config32(SA_DEV_ROOT, BGSM), 1*MiB);
141 }
142 
sa_get_tseg_base(void)143 uintptr_t sa_get_tseg_base(void)
144 {
145 	/* All regions concerned for have 1 MiB alignment. */
146 	return ALIGN_DOWN(pci_read_config32(SA_DEV_ROOT, TSEG), 1*MiB);
147 }
148 
sa_get_tseg_size(void)149 size_t sa_get_tseg_size(void)
150 {
151 	return sa_get_gsm_base() - sa_get_tseg_base();
152 }
153 
txt_get_chipset_dpr(void)154 union dpr_register txt_get_chipset_dpr(void)
155 {
156 	return (union dpr_register) { .raw = pci_read_config32(SA_DEV_ROOT, DPR) };
157 }
158