coreboot/src/devices/pci_ops.c
<<
>>
Prefs
   1/*
   2 * This file is part of the coreboot project.
   3 *
   4 * Copyright (C) 2004 Linux Networx
   5 * (Written by Eric Biederman <ebiederman@lnxi.com> for Linux Networx)
   6 * Copyright (C) 2009 coresystems GmbH
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License as published by
  10 * the Free Software Foundation; version 2 of the License.
  11 *
  12 * This program is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 * GNU General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU General Public License
  18 * along with this program; if not, write to the Free Software
  19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
  20 */
  21
  22#include <console/console.h>
  23#include <arch/pciconf.h>
  24#include <device/pci.h>
  25#include <device/pci_ids.h>
  26#include <device/pci_ops.h>
  27
  28/*
  29 * The only consumer of the return value of get_pbus() is ops_pci_bus().
  30 * ops_pci_bus() can handle being passed NULL and auto-picks working ops.
  31 */
  32static struct bus *get_pbus(device_t dev)
  33{
  34        struct bus *pbus = NULL;
  35
  36        if (!dev)
  37                die("get_pbus: dev is NULL!\n");
  38        else
  39                pbus = dev->bus;
  40
  41        while (pbus && pbus->dev && !ops_pci_bus(pbus)) {
  42                if (pbus == pbus->dev->bus) {
  43                        printk(BIOS_ALERT, "%s in endless loop looking for a "
  44                               "parent bus with ops_pci_bus for %s, breaking "
  45                               "out.\n", __func__, dev_path(dev));
  46                        break;
  47                }
  48                pbus = pbus->dev->bus;
  49        }
  50
  51        if (!pbus || !pbus->dev || !pbus->dev->ops
  52            || !pbus->dev->ops->ops_pci_bus) {
  53                /* This can happen before the device tree is fully set up. */
  54
  55                // printk(BIOS_EMERG, "%s: Cannot find PCI bus operations.\n",
  56                // dev_path(dev));
  57
  58                pbus = NULL;
  59        }
  60
  61        return pbus;
  62}
  63
  64u8 pci_read_config8(device_t dev, unsigned int where)
  65{
  66        struct bus *pbus = get_pbus(dev);
  67        return ops_pci_bus(pbus)->read8(pbus, dev->bus->secondary,
  68                                        dev->path.pci.devfn, where);
  69}
  70
  71u16 pci_read_config16(device_t dev, unsigned int where)
  72{
  73        struct bus *pbus = get_pbus(dev);
  74        return ops_pci_bus(pbus)->read16(pbus, dev->bus->secondary,
  75                                         dev->path.pci.devfn, where);
  76}
  77
  78u32 pci_read_config32(device_t dev, unsigned int where)
  79{
  80        struct bus *pbus = get_pbus(dev);
  81        return ops_pci_bus(pbus)->read32(pbus, dev->bus->secondary,
  82                                         dev->path.pci.devfn, where);
  83}
  84
  85void pci_write_config8(device_t dev, unsigned int where, u8 val)
  86{
  87        struct bus *pbus = get_pbus(dev);
  88        ops_pci_bus(pbus)->write8(pbus, dev->bus->secondary,
  89                                  dev->path.pci.devfn, where, val);
  90}
  91
  92void pci_write_config16(device_t dev, unsigned int where, u16 val)
  93{
  94        struct bus *pbus = get_pbus(dev);
  95        ops_pci_bus(pbus)->write16(pbus, dev->bus->secondary,
  96                                   dev->path.pci.devfn, where, val);
  97}
  98
  99void pci_write_config32(device_t dev, unsigned int where, u32 val)
 100{
 101        struct bus *pbus = get_pbus(dev);
 102        ops_pci_bus(pbus)->write32(pbus, dev->bus->secondary,
 103                                   dev->path.pci.devfn, where, val);
 104}
 105
 106#if CONFIG_MMCONF_SUPPORT
 107u8 pci_mmio_read_config8(device_t dev, unsigned int where)
 108{
 109        struct bus *pbus = get_pbus(dev);
 110        return pci_ops_mmconf.read8(pbus, dev->bus->secondary,
 111                                    dev->path.pci.devfn, where);
 112}
 113
 114u16 pci_mmio_read_config16(device_t dev, unsigned int where)
 115{
 116        struct bus *pbus = get_pbus(dev);
 117        return pci_ops_mmconf.read16(pbus, dev->bus->secondary,
 118                                     dev->path.pci.devfn, where);
 119}
 120
 121u32 pci_mmio_read_config32(device_t dev, unsigned int where)
 122{
 123        struct bus *pbus = get_pbus(dev);
 124        return pci_ops_mmconf.read32(pbus, dev->bus->secondary,
 125                                     dev->path.pci.devfn, where);
 126}
 127
 128void pci_mmio_write_config8(device_t dev, unsigned int where, u8 val)
 129{
 130        struct bus *pbus = get_pbus(dev);
 131        pci_ops_mmconf.write8(pbus, dev->bus->secondary, dev->path.pci.devfn,
 132                              where, val);
 133}
 134
 135void pci_mmio_write_config16(device_t dev, unsigned int where, u16 val)
 136{
 137        struct bus *pbus = get_pbus(dev);
 138        pci_ops_mmconf.write16(pbus, dev->bus->secondary, dev->path.pci.devfn,
 139                               where, val);
 140}
 141
 142void pci_mmio_write_config32(device_t dev, unsigned int where, u32 val)
 143{
 144        struct bus *pbus = get_pbus(dev);
 145        pci_ops_mmconf.write32(pbus, dev->bus->secondary, dev->path.pci.devfn,
 146                               where, val);
 147}
 148
 149#endif
 150
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.