2 * This file is part of the coreboot project.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
17 #include <device/mmio.h>
18 #include <device/pci_ops.h>
19 #include <device/pci.h>
20 #include <device/pci_def.h>
21 #include <device/device.h>
23 #include <soc/iomap.h>
24 #include <soc/soc_util.h>
26 #include <soc/smbus.h>
28 #include <soc/pci_devs.h>
29 #include <soc/systemagent.h>
31 #ifdef __SIMPLE_DEVICE__
32 pci_devfn_t
get_hostbridge_dev(void)
34 return PCI_DEV(0, SA_DEV
, SA_FUNC
);
37 struct device
*get_hostbridge_dev(void)
39 return pcidev_on_root(SA_DEV
, SA_FUNC
);
43 #ifdef __SIMPLE_DEVICE__
44 pci_devfn_t
get_lpc_dev(void)
46 return PCI_DEV(0, LPC_DEV
, LPC_FUNC
);
49 struct device
*get_lpc_dev(void)
51 return pcidev_on_root(LPC_DEV
, LPC_FUNC
);
55 #ifdef __SIMPLE_DEVICE__
56 pci_devfn_t
get_pmc_dev(void)
58 return PCI_DEV(0, PMC_DEV
, PMC_FUNC
);
61 struct device
*get_pmc_dev(void)
63 return pcidev_on_root(PMC_DEV
, PMC_FUNC
);
67 #ifdef __SIMPLE_DEVICE__
68 pci_devfn_t
get_smbus_dev(void)
70 return PCI_DEV(0, SMBUS_DEV
, SMBUS_FUNC
);
73 struct device
*get_smbus_dev(void)
75 return pcidev_on_root(SMBUS_DEV
, SMBUS_FUNC
);
79 uint32_t get_pciebase(void)
81 #ifdef __SIMPLE_DEVICE__
88 dev
= get_hostbridge_dev();
92 pciexbar_reg
= pci_read_config32(dev
, PCIEXBAR
);
94 if (!(pciexbar_reg
& (1 << 0)))
97 switch (pciexbar_reg
& MASK_PCIEXBAR_LENGTH
) {
98 case MASK_PCIEXBAR_LENGTH_256M
:
99 pciexbar_reg
&= MASK_PCIEXBAR_256M
;
101 case MASK_PCIEXBAR_LENGTH_128M
:
102 pciexbar_reg
&= MASK_PCIEXBAR_128M
;
104 case MASK_PCIEXBAR_LENGTH_64M
:
105 pciexbar_reg
&= MASK_PCIEXBAR_64M
;
108 pciexbar_reg
&= MASK_PCIEXBAR_256M
;
115 uint32_t get_pcielength(void)
117 #ifdef __SIMPLE_DEVICE__
124 dev
= get_hostbridge_dev();
128 pciexbar_reg
= pci_read_config32(dev
, PCIEXBAR
);
130 if (!(pciexbar_reg
& (1 << 0)))
133 switch (pciexbar_reg
& MASK_PCIEXBAR_LENGTH
) {
134 case MASK_PCIEXBAR_LENGTH_256M
:
137 case MASK_PCIEXBAR_LENGTH_128M
:
140 case MASK_PCIEXBAR_LENGTH_64M
:
151 uint32_t get_tseg_memory(void)
153 #ifdef __SIMPLE_DEVICE__
158 dev
= get_hostbridge_dev();
163 return pci_read_config32(dev
, TSEGMB
) & MASK_TSEGMB
;
166 uint32_t get_top_of_low_memory(void)
168 #ifdef __SIMPLE_DEVICE__
173 dev
= get_hostbridge_dev();
178 return pci_read_config32(dev
, TOLUD
) & MASK_TOLUD
;
181 uint64_t get_top_of_upper_memory(void)
183 #ifdef __SIMPLE_DEVICE__
188 dev
= get_hostbridge_dev();
193 return ((uint64_t)(pci_read_config32(dev
, TOUUD_HI
) & MASK_TOUUD_HI
)
195 (uint64_t)(pci_read_config32(dev
, TOUUD_LO
) & MASK_TOUUD_LO
);
198 uint16_t get_pmbase(void)
200 #ifdef __SIMPLE_DEVICE__
210 return pci_read_config16(dev
, PMC_ACPI_BASE
) & 0xfff8;
213 uint16_t get_tcobase(void)
215 #ifdef __SIMPLE_DEVICE__
220 dev
= get_smbus_dev();
225 return pci_read_config16(dev
, TCOBASE
) & MASK_TCOBASE
;
228 void mmio_andthenor32(void *addr
, uint32_t val2and
, uint32_t val2or
)
232 reg32
= read32(addr
);
233 reg32
&= (uint32_t)val2and
;
234 reg32
|= (uint32_t)val2or
;
235 write32(addr
, reg32
);
238 uint8_t silicon_stepping(void)
241 #ifdef __SIMPLE_DEVICE__
251 revision_id
= pci_read_config8(dev
, PCI_REVISION_ID
);
256 void *memcpy_s(void *dest
, const void *src
, size_t n
)
261 dp
= (uint8_t *)dest
;
277 * overlap is undefined behavior, do not allow
279 if (((dp
> sp
) && (dp
< (sp
+ n
))) || ((sp
> dp
) && (sp
< (dp
+ n
))))
283 * now perform the copy
286 /* Original memcpy() function */
287 unsigned long d0
, d1
, d2
;
298 : "=&c"(d0
), "=&D"(d1
), "=&S"(d2
)
299 : "0"(n
>> 2), "g"(n
& 3), "1"(dest
), "2"(src
)