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