blob: 8f26ff29b0d2fa3f15b619dc627f42c0b0e3f72b [file] [log] [blame]
Stefan Reinauer00636b02012-04-04 00:08:51 +02001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2007-2009 coresystems GmbH
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
Stefan Reinauer00636b02012-04-04 00:08:51 +020014 */
15
Kyösti Mälkki54d6abd2013-06-19 23:05:00 +030016#ifndef _PCI_MMIO_CFG_H
17#define _PCI_MMIO_CFG_H
18
Kyösti Mälkki8fd78a62019-01-23 15:59:38 +020019#include <stdint.h>
Kyösti Mälkki13f66502019-03-03 08:01:05 +020020#include <device/mmio.h>
Kyösti Mälkki8fd78a62019-01-23 15:59:38 +020021#include <device/pci_type.h>
Kyösti Mälkki54d6abd2013-06-19 23:05:00 +030022
Kyösti Mälkkid2cdfff2019-03-05 07:56:38 +020023#if !defined(__ROMCC__)
24
25/* By not assigning this to CONFIG_MMCONF_BASE_ADDRESS here we
26 * prevent some sub-optimal constant folding. */
27extern u8 *const pci_mmconf;
28
29/* Using a unique datatype for MMIO writes makes the pointers to _not_
30 * qualify for pointer aliasing with any other objects in memory.
31 *
32 * MMIO offset is a value originally derived from 'struct device *'
33 * in ramstage. For the compiler to not discard this MMIO offset value
34 * from CPU registers after any MMIO writes, -fstrict-aliasing has to
35 * be also set for the build.
36 *
37 * Bottom 12 bits (4 KiB) are reserved to address the registers of a
38 * single PCI function. Declare the bank as a union to avoid some casting
39 * in the functions below.
40 */
41union pci_bank {
42 uint8_t reg8[4096];
43 uint16_t reg16[4096 / sizeof(uint16_t)];
44 uint32_t reg32[4096 / sizeof(uint32_t)];
45};
46
47static __always_inline
48volatile union pci_bank *pcicfg(pci_devfn_t dev)
49{
50 return (void *)&pci_mmconf[PCI_DEVFN_OFFSET(dev)];
51}
Stefan Reinauer00636b02012-04-04 00:08:51 +020052
Aaron Durbin75a62e72018-09-13 02:10:45 -060053static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +020054uint8_t pci_mmio_read_config8(pci_devfn_t dev, uint16_t reg)
Stefan Reinauer00636b02012-04-04 00:08:51 +020055{
Kyösti Mälkkid2cdfff2019-03-05 07:56:38 +020056 return pcicfg(dev)->reg8[reg];
Stefan Reinauer00636b02012-04-04 00:08:51 +020057}
58
Aaron Durbin75a62e72018-09-13 02:10:45 -060059static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +020060uint16_t pci_mmio_read_config16(pci_devfn_t dev, uint16_t reg)
Stefan Reinauer00636b02012-04-04 00:08:51 +020061{
Kyösti Mälkkid2cdfff2019-03-05 07:56:38 +020062 return pcicfg(dev)->reg16[reg / sizeof(uint16_t)];
Stefan Reinauer00636b02012-04-04 00:08:51 +020063}
64
Aaron Durbin75a62e72018-09-13 02:10:45 -060065static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +020066uint32_t pci_mmio_read_config32(pci_devfn_t dev, uint16_t reg)
Stefan Reinauer00636b02012-04-04 00:08:51 +020067{
Kyösti Mälkkid2cdfff2019-03-05 07:56:38 +020068 return pcicfg(dev)->reg32[reg / sizeof(uint32_t)];
Stefan Reinauer00636b02012-04-04 00:08:51 +020069}
70
Aaron Durbin75a62e72018-09-13 02:10:45 -060071static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +020072void pci_mmio_write_config8(pci_devfn_t dev, uint16_t reg, uint8_t value)
Stefan Reinauer00636b02012-04-04 00:08:51 +020073{
Kyösti Mälkkid2cdfff2019-03-05 07:56:38 +020074 pcicfg(dev)->reg8[reg] = value;
Stefan Reinauer00636b02012-04-04 00:08:51 +020075}
76
Aaron Durbin75a62e72018-09-13 02:10:45 -060077static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +020078void pci_mmio_write_config16(pci_devfn_t dev, uint16_t reg, uint16_t value)
Stefan Reinauer00636b02012-04-04 00:08:51 +020079{
Kyösti Mälkkid2cdfff2019-03-05 07:56:38 +020080 pcicfg(dev)->reg16[reg / sizeof(uint16_t)] = value;
Stefan Reinauer00636b02012-04-04 00:08:51 +020081}
82
Aaron Durbin75a62e72018-09-13 02:10:45 -060083static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +020084void pci_mmio_write_config32(pci_devfn_t dev, uint16_t reg, uint32_t value)
Stefan Reinauer00636b02012-04-04 00:08:51 +020085{
Kyösti Mälkkid2cdfff2019-03-05 07:56:38 +020086 pcicfg(dev)->reg32[reg / sizeof(uint32_t)] = value;
Stefan Reinauer00636b02012-04-04 00:08:51 +020087}
88
Michael Niewöhner8f221362019-11-08 22:02:02 +010089static __always_inline
90uint8_t *pci_mmio_config8_addr(pci_devfn_t dev, uint16_t reg)
91{
92 return (uint8_t *)&pcicfg(dev)->reg8[reg];
93}
94
95static __always_inline
96uint16_t *pci_mmio_config16_addr(pci_devfn_t dev, uint16_t reg)
97{
98 return (uint16_t *)&pcicfg(dev)->reg16[reg / sizeof(uint16_t)];
99}
100
101static __always_inline
102uint32_t *pci_mmio_config32_addr(pci_devfn_t dev, uint16_t reg)
103{
104 return (uint32_t *)&pcicfg(dev)->reg32[reg / sizeof(uint32_t)];
105}
106
Kyösti Mälkkid2cdfff2019-03-05 07:56:38 +0200107#endif /* !defined(__ROMCC__) */
108
Julius Wernercd49cce2019-03-05 16:53:33 -0800109#if CONFIG(MMCONF_SUPPORT)
Kyösti Mälkki2d8aff32019-01-23 16:44:55 +0200110
Arthur Heymans15fcc862019-10-08 11:29:12 +0200111#if CONFIG_MMCONF_BASE_ADDRESS == 0
112#error "CONFIG_MMCONF_BASE_ADDRESS undefined!"
113#endif
114
Kyösti Mälkki92b52962019-03-01 08:08:28 +0200115/* Avoid name collisions as different stages have different signature
116 * for these functions. The _s_ stands for simple, fundamental IO or
117 * MMIO variant.
118 */
119
Kyösti Mälkki2d8aff32019-01-23 16:44:55 +0200120static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200121uint8_t pci_s_read_config8(pci_devfn_t dev, uint16_t reg)
Kyösti Mälkki2d8aff32019-01-23 16:44:55 +0200122{
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200123 return pci_mmio_read_config8(dev, reg);
Kyösti Mälkki2d8aff32019-01-23 16:44:55 +0200124}
125
126static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200127uint16_t pci_s_read_config16(pci_devfn_t dev, uint16_t reg)
Kyösti Mälkki2d8aff32019-01-23 16:44:55 +0200128{
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200129 return pci_mmio_read_config16(dev, reg);
Kyösti Mälkki2d8aff32019-01-23 16:44:55 +0200130}
131
132static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200133uint32_t pci_s_read_config32(pci_devfn_t dev, uint16_t reg)
Kyösti Mälkki2d8aff32019-01-23 16:44:55 +0200134{
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200135 return pci_mmio_read_config32(dev, reg);
Kyösti Mälkki2d8aff32019-01-23 16:44:55 +0200136}
137
138static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200139void pci_s_write_config8(pci_devfn_t dev, uint16_t reg, uint8_t value)
Kyösti Mälkki2d8aff32019-01-23 16:44:55 +0200140{
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200141 pci_mmio_write_config8(dev, reg, value);
Kyösti Mälkki2d8aff32019-01-23 16:44:55 +0200142}
143
144static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200145void pci_s_write_config16(pci_devfn_t dev, uint16_t reg, uint16_t value)
Kyösti Mälkki2d8aff32019-01-23 16:44:55 +0200146{
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200147 pci_mmio_write_config16(dev, reg, value);
Kyösti Mälkki2d8aff32019-01-23 16:44:55 +0200148}
149
150static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200151void pci_s_write_config32(pci_devfn_t dev, uint16_t reg, uint32_t value)
Kyösti Mälkki2d8aff32019-01-23 16:44:55 +0200152{
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200153 pci_mmio_write_config32(dev, reg, value);
Kyösti Mälkki2d8aff32019-01-23 16:44:55 +0200154}
Kyösti Mälkki2d8aff32019-01-23 16:44:55 +0200155
156#endif
157
Kyösti Mälkki54d6abd2013-06-19 23:05:00 +0300158#endif /* _PCI_MMIO_CFG_H */