blob: e3c5fe4873ccfd2bac4c3116f919bfe3c6cfae98 [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
Kyösti Mälkkid2cdfff2019-03-05 07:56:38 +020089#endif /* !defined(__ROMCC__) */
90
Julius Wernercd49cce2019-03-05 16:53:33 -080091#if CONFIG(MMCONF_SUPPORT)
Kyösti Mälkki2d8aff32019-01-23 16:44:55 +020092
Arthur Heymans15fcc862019-10-08 11:29:12 +020093#if CONFIG_MMCONF_BASE_ADDRESS == 0
94#error "CONFIG_MMCONF_BASE_ADDRESS undefined!"
95#endif
96
Kyösti Mälkki92b52962019-03-01 08:08:28 +020097/* Avoid name collisions as different stages have different signature
98 * for these functions. The _s_ stands for simple, fundamental IO or
99 * MMIO variant.
100 */
101
Kyösti Mälkki2d8aff32019-01-23 16:44:55 +0200102static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200103uint8_t pci_s_read_config8(pci_devfn_t dev, uint16_t reg)
Kyösti Mälkki2d8aff32019-01-23 16:44:55 +0200104{
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200105 return pci_mmio_read_config8(dev, reg);
Kyösti Mälkki2d8aff32019-01-23 16:44:55 +0200106}
107
108static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200109uint16_t pci_s_read_config16(pci_devfn_t dev, uint16_t reg)
Kyösti Mälkki2d8aff32019-01-23 16:44:55 +0200110{
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200111 return pci_mmio_read_config16(dev, reg);
Kyösti Mälkki2d8aff32019-01-23 16:44:55 +0200112}
113
114static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200115uint32_t pci_s_read_config32(pci_devfn_t dev, uint16_t reg)
Kyösti Mälkki2d8aff32019-01-23 16:44:55 +0200116{
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200117 return pci_mmio_read_config32(dev, reg);
Kyösti Mälkki2d8aff32019-01-23 16:44:55 +0200118}
119
120static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200121void pci_s_write_config8(pci_devfn_t dev, uint16_t reg, uint8_t value)
Kyösti Mälkki2d8aff32019-01-23 16:44:55 +0200122{
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200123 pci_mmio_write_config8(dev, reg, value);
Kyösti Mälkki2d8aff32019-01-23 16:44:55 +0200124}
125
126static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200127void pci_s_write_config16(pci_devfn_t dev, uint16_t reg, uint16_t value)
Kyösti Mälkki2d8aff32019-01-23 16:44:55 +0200128{
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200129 pci_mmio_write_config16(dev, reg, value);
Kyösti Mälkki2d8aff32019-01-23 16:44:55 +0200130}
131
132static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200133void pci_s_write_config32(pci_devfn_t dev, uint16_t reg, uint32_t value)
Kyösti Mälkki2d8aff32019-01-23 16:44:55 +0200134{
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200135 pci_mmio_write_config32(dev, reg, value);
Kyösti Mälkki2d8aff32019-01-23 16:44:55 +0200136}
Kyösti Mälkki2d8aff32019-01-23 16:44:55 +0200137
138#endif
139
Kyösti Mälkki54d6abd2013-06-19 23:05:00 +0300140#endif /* _PCI_MMIO_CFG_H */