xref: /aosp_15_r20/external/coreboot/src/soc/intel/denverton_ns/soc_util.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <stdint.h>
4 #include <device/mmio.h>
5 #include <device/pci_ops.h>
6 #include <device/pci.h>
7 #include <device/device.h>
8 #include <string.h>
9 #include <soc/iomap.h>
10 #include <soc/soc_util.h>
11 #include <soc/pmc.h>
12 #include <soc/smbus.h>
13 #include <soc/lpc.h>
14 #include <soc/pci_devs.h>
15 #include <soc/systemagent.h>
16 
17 #ifdef __SIMPLE_DEVICE__
get_hostbridge_dev(void)18 pci_devfn_t get_hostbridge_dev(void)
19 {
20 	return PCI_DEV(0, SA_DEV, SA_FUNC);
21 }
22 #else
get_hostbridge_dev(void)23 struct device *get_hostbridge_dev(void)
24 {
25 	return pcidev_on_root(SA_DEV, SA_FUNC);
26 }
27 #endif
28 
29 #ifdef __SIMPLE_DEVICE__
get_lpc_dev(void)30 pci_devfn_t get_lpc_dev(void)
31 {
32 	return PCI_DEV(0, LPC_DEV, LPC_FUNC);
33 }
34 #else
get_lpc_dev(void)35 struct device *get_lpc_dev(void)
36 {
37 	return pcidev_on_root(LPC_DEV, LPC_FUNC);
38 }
39 #endif
40 
41 #ifdef __SIMPLE_DEVICE__
get_pmc_dev(void)42 pci_devfn_t get_pmc_dev(void)
43 {
44 	return PCI_DEV(0, PMC_DEV, PMC_FUNC);
45 }
46 #else
get_pmc_dev(void)47 struct device *get_pmc_dev(void)
48 {
49 	return pcidev_on_root(PMC_DEV, PMC_FUNC);
50 }
51 #endif
52 
53 #ifdef __SIMPLE_DEVICE__
get_smbus_dev(void)54 pci_devfn_t get_smbus_dev(void)
55 {
56 	return PCI_DEV(0, SMBUS_DEV, SMBUS_FUNC);
57 }
58 #else
get_smbus_dev(void)59 struct device *get_smbus_dev(void)
60 {
61 	return pcidev_on_root(SMBUS_DEV, SMBUS_FUNC);
62 }
63 #endif
64 
get_pciebase(void)65 uint32_t get_pciebase(void)
66 {
67 #ifdef __SIMPLE_DEVICE__
68 	pci_devfn_t dev;
69 #else
70 	struct device *dev;
71 #endif
72 	u32 pciexbar_reg;
73 
74 	dev = get_hostbridge_dev();
75 	if (!dev)
76 		return 0;
77 
78 	pciexbar_reg = pci_read_config32(dev, PCIEXBAR);
79 
80 	if (!(pciexbar_reg & (1 << 0)))
81 		return 0;
82 
83 	switch (pciexbar_reg & MASK_PCIEXBAR_LENGTH) {
84 	case MASK_PCIEXBAR_LENGTH_256M:
85 		pciexbar_reg &= MASK_PCIEXBAR_256M;
86 		break;
87 	case MASK_PCIEXBAR_LENGTH_128M:
88 		pciexbar_reg &= MASK_PCIEXBAR_128M;
89 		break;
90 	case MASK_PCIEXBAR_LENGTH_64M:
91 		pciexbar_reg &= MASK_PCIEXBAR_64M;
92 		break;
93 	default:
94 		pciexbar_reg &= MASK_PCIEXBAR_256M;
95 		break;
96 	}
97 
98 	return pciexbar_reg;
99 }
100 
get_pcielength(void)101 uint32_t get_pcielength(void)
102 {
103 #ifdef __SIMPLE_DEVICE__
104 	pci_devfn_t dev;
105 #else
106 	struct device *dev;
107 #endif
108 	u32 pciexbar_reg;
109 
110 	dev = get_hostbridge_dev();
111 	if (!dev)
112 		return 0;
113 
114 	pciexbar_reg = pci_read_config32(dev, PCIEXBAR);
115 
116 	if (!(pciexbar_reg & (1 << 0)))
117 		return 0;
118 
119 	switch (pciexbar_reg & MASK_PCIEXBAR_LENGTH) {
120 	case MASK_PCIEXBAR_LENGTH_256M:
121 		pciexbar_reg = 256;
122 		break;
123 	case MASK_PCIEXBAR_LENGTH_128M:
124 		pciexbar_reg = 128;
125 		break;
126 	case MASK_PCIEXBAR_LENGTH_64M:
127 		pciexbar_reg = 64;
128 		break;
129 	default:
130 		pciexbar_reg = 64;
131 		break;
132 	}
133 
134 	return pciexbar_reg;
135 }
136 
get_tseg_memory(void)137 uint32_t get_tseg_memory(void)
138 {
139 #ifdef __SIMPLE_DEVICE__
140 	pci_devfn_t dev;
141 #else
142 	struct device *dev;
143 #endif
144 	dev = get_hostbridge_dev();
145 
146 	if (!dev)
147 		return 0;
148 
149 	return pci_read_config32(dev, TSEGMB) & MASK_TSEGMB;
150 }
151 
get_top_of_low_memory(void)152 uint32_t get_top_of_low_memory(void)
153 {
154 #ifdef __SIMPLE_DEVICE__
155 	pci_devfn_t dev;
156 #else
157 	struct device *dev;
158 #endif
159 	dev = get_hostbridge_dev();
160 
161 	if (!dev)
162 		return 0;
163 
164 	return pci_read_config32(dev, TOLUD) & MASK_TOLUD;
165 }
166 
get_top_of_upper_memory(void)167 uint64_t get_top_of_upper_memory(void)
168 {
169 #ifdef __SIMPLE_DEVICE__
170 	pci_devfn_t dev;
171 #else
172 	struct device *dev;
173 #endif
174 	dev = get_hostbridge_dev();
175 
176 	if (!dev)
177 		return 0;
178 
179 	return ((uint64_t)(pci_read_config32(dev, TOUUD_HI) & MASK_TOUUD_HI)
180 		<< 32) +
181 	       (uint64_t)(pci_read_config32(dev, TOUUD_LO) & MASK_TOUUD_LO);
182 }
183 
get_pmbase(void)184 uint16_t get_pmbase(void)
185 {
186 #ifdef __SIMPLE_DEVICE__
187 	pci_devfn_t dev;
188 #else
189 	struct device *dev;
190 #endif
191 	dev = get_pmc_dev();
192 
193 	if (!dev)
194 		return 0;
195 
196 	return pci_read_config16(dev, PMC_ACPI_BASE) & 0xfff8;
197 }
198 
get_tcobase(void)199 uint16_t get_tcobase(void)
200 {
201 #ifdef __SIMPLE_DEVICE__
202 	pci_devfn_t dev;
203 #else
204 	struct device *dev;
205 #endif
206 	dev = get_smbus_dev();
207 
208 	if (!dev)
209 		return 0;
210 
211 	return pci_read_config16(dev, TCOBASE) & MASK_TCOBASE;
212 }
213 
mmio_andthenor32(void * addr,uint32_t val2and,uint32_t val2or)214 void mmio_andthenor32(void *addr, uint32_t val2and, uint32_t val2or)
215 {
216 	uint32_t reg32;
217 
218 	reg32 = read32(addr);
219 	reg32 &= (uint32_t)val2and;
220 	reg32 |= (uint32_t)val2or;
221 	write32(addr, reg32);
222 }
223 
silicon_stepping(void)224 uint8_t silicon_stepping(void)
225 {
226 	uint8_t revision_id;
227 #ifdef __SIMPLE_DEVICE__
228 	pci_devfn_t dev;
229 #else
230 	struct device *dev;
231 #endif
232 	dev = get_lpc_dev();
233 
234 	if (!dev)
235 		return 0;
236 
237 	revision_id = pci_read_config8(dev, PCI_REVISION_ID);
238 
239 	return revision_id;
240 }
241 
memcpy_s(void * dest,const void * src,size_t n)242 void *memcpy_s(void *dest, const void *src, size_t n)
243 {
244 	uint8_t *dp;
245 	const uint8_t *sp;
246 
247 	dp = (uint8_t *)dest;
248 	sp = (uint8_t *)src;
249 
250 	if (!n)
251 		return dest;
252 
253 	if (n > UINT32_MAX)
254 		return dest;
255 
256 	if (!dp)
257 		return dest;
258 
259 	if (!sp)
260 		return dest;
261 
262 	/*
263 	 * overlap is undefined behavior, do not allow
264 	 */
265 	if (((dp > sp) && (dp < (sp + n))) || ((sp > dp) && (sp < (dp + n))))
266 		return dest;
267 
268 	/*
269 	 * now perform the copy
270 	 */
271 
272 	/* Original memcpy() function */
273 	unsigned long d0, d1, d2;
274 
275 	asm volatile(
276 #if ENV_X86_64
277 		"rep ; movsd\n\t"
278 		"mov %4,%%rcx\n\t"
279 #else
280 		"rep ; movsl\n\t"
281 		"movl %4,%%ecx\n\t"
282 #endif
283 		"rep ; movsb\n\t"
284 		: "=&c"(d0), "=&D"(d1), "=&S"(d2)
285 		: "0"(n >> 2), "g"(n & 3), "1"(dest), "2"(src)
286 		: "memory");
287 
288 	return dest;
289 }
290