2003-04-24 08:25:08 +02:00
|
|
|
/*
|
|
|
|
* PCI defines and function prototypes
|
|
|
|
* Copyright 1994, Drew Eckhardt
|
|
|
|
* Copyright 1997--1999 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
|
|
|
|
*
|
|
|
|
* For more information, please consult the following manuals (look at
|
|
|
|
* http://www.pcisig.com/ for how to get them):
|
|
|
|
*
|
|
|
|
* PCI BIOS Specification
|
|
|
|
* PCI Local Bus Specification
|
|
|
|
* PCI to PCI Bridge Specification
|
|
|
|
* PCI System Design Guide
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef PCI_H
|
|
|
|
#define PCI_H
|
|
|
|
|
2010-11-05 00:23:47 +01:00
|
|
|
#include <stdint.h>
|
2003-05-19 21:16:21 +02:00
|
|
|
#include <device/pci_def.h>
|
2003-04-24 08:25:08 +02:00
|
|
|
#include <device/resource.h>
|
|
|
|
#include <device/device.h>
|
|
|
|
#include <device/pci_ops.h>
|
2005-01-11 00:16:22 +01:00
|
|
|
#include <device/pci_rom.h>
|
2003-04-24 08:25:08 +02:00
|
|
|
|
2004-10-14 22:54:17 +02:00
|
|
|
/* Common pci operations without a standard interface */
|
|
|
|
struct pci_operations {
|
2004-11-25 18:37:19 +01:00
|
|
|
/* set the Subsystem IDs for the PCI device */
|
2004-10-14 22:54:17 +02:00
|
|
|
void (*set_subsystem)(device_t dev, unsigned vendor, unsigned device);
|
|
|
|
};
|
|
|
|
|
2004-11-18 23:38:08 +01:00
|
|
|
/* Common pci bus operations */
|
|
|
|
struct pci_bus_operations {
|
2006-10-04 22:46:15 +02:00
|
|
|
uint8_t (*read8) (struct bus *pbus, int bus, int devfn, int where);
|
|
|
|
uint16_t (*read16) (struct bus *pbus, int bus, int devfn, int where);
|
|
|
|
uint32_t (*read32) (struct bus *pbus, int bus, int devfn, int where);
|
|
|
|
void (*write8) (struct bus *pbus, int bus, int devfn, int where, uint8_t val);
|
|
|
|
void (*write16) (struct bus *pbus, int bus, int devfn, int where, uint16_t val);
|
|
|
|
void (*write32) (struct bus *pbus, int bus, int devfn, int where, uint32_t val);
|
2004-11-18 23:38:08 +01:00
|
|
|
};
|
|
|
|
|
2003-04-24 08:25:08 +02:00
|
|
|
struct pci_driver {
|
2009-10-27 22:49:33 +01:00
|
|
|
const struct device_operations *ops;
|
2003-04-24 08:25:08 +02:00
|
|
|
unsigned short vendor;
|
|
|
|
unsigned short device;
|
|
|
|
};
|
|
|
|
|
2004-10-14 22:54:17 +02:00
|
|
|
#define __pci_driver __attribute__ ((used,__section__(".rodata.pci_driver")))
|
2004-03-23 22:28:05 +01:00
|
|
|
/** start of compile time generated pci driver array */
|
2003-04-24 08:25:08 +02:00
|
|
|
extern struct pci_driver pci_drivers[];
|
2004-03-23 22:28:05 +01:00
|
|
|
/** end of compile time generated pci driver array */
|
2003-04-24 08:25:08 +02:00
|
|
|
extern struct pci_driver epci_drivers[];
|
|
|
|
|
|
|
|
|
2005-07-08 04:49:49 +02:00
|
|
|
extern struct device_operations default_pci_ops_dev;
|
|
|
|
extern struct device_operations default_pci_ops_bus;
|
2003-04-24 08:25:08 +02:00
|
|
|
|
2003-09-02 05:36:25 +02:00
|
|
|
void pci_dev_read_resources(device_t dev);
|
|
|
|
void pci_bus_read_resources(device_t dev);
|
|
|
|
void pci_dev_set_resources(device_t dev);
|
|
|
|
void pci_dev_enable_resources(device_t dev);
|
|
|
|
void pci_bus_enable_resources(device_t dev);
|
2005-07-08 04:49:49 +02:00
|
|
|
void pci_bus_reset(struct bus *bus);
|
|
|
|
device_t pci_probe_dev(device_t dev, struct bus *bus, unsigned devfn);
|
|
|
|
unsigned int do_pci_scan_bridge(device_t bus, unsigned int max,
|
2010-04-27 08:56:47 +02:00
|
|
|
unsigned int (*do_scan_bus)(struct bus *bus,
|
2005-07-08 04:49:49 +02:00
|
|
|
unsigned min_devfn, unsigned max_devfn, unsigned int max));
|
2003-09-02 05:36:25 +02:00
|
|
|
unsigned int pci_scan_bridge(device_t bus, unsigned int max);
|
|
|
|
unsigned int pci_scan_bus(struct bus *bus, unsigned min_devfn, unsigned max_devfn, unsigned int max);
|
2005-07-08 04:49:49 +02:00
|
|
|
uint8_t pci_moving_config8(struct device *dev, unsigned reg);
|
|
|
|
uint16_t pci_moving_config16(struct device *dev, unsigned reg);
|
|
|
|
uint32_t pci_moving_config32(struct device *dev, unsigned reg);
|
|
|
|
unsigned pci_find_next_capability(device_t dev, unsigned cap, unsigned last);
|
|
|
|
unsigned pci_find_capability(device_t dev, unsigned cap);
|
2004-10-14 22:54:17 +02:00
|
|
|
struct resource *pci_get_resource(struct device *dev, unsigned long index);
|
2004-10-21 12:44:08 +02:00
|
|
|
void pci_dev_set_subsystem(device_t dev, unsigned vendor, unsigned device);
|
2008-12-18 19:24:11 +01:00
|
|
|
void pci_dev_init(struct device *dev);
|
2009-07-21 23:36:41 +02:00
|
|
|
|
2008-12-18 19:24:11 +01:00
|
|
|
void pci_assign_irqs(unsigned bus, unsigned slot,
|
|
|
|
const unsigned char pIntAtoD[4]);
|
2003-04-24 08:25:08 +02:00
|
|
|
|
|
|
|
#define PCI_IO_BRIDGE_ALIGN 4096
|
|
|
|
#define PCI_MEM_BRIDGE_ALIGN (1024*1024)
|
|
|
|
|
2004-11-18 23:38:08 +01:00
|
|
|
static inline const struct pci_operations *ops_pci(device_t dev)
|
2004-10-14 22:54:17 +02:00
|
|
|
{
|
2004-11-18 23:38:08 +01:00
|
|
|
const struct pci_operations *pops;
|
2004-10-14 22:54:17 +02:00
|
|
|
pops = 0;
|
|
|
|
if (dev && dev->ops) {
|
|
|
|
pops = dev->ops->ops_pci;
|
|
|
|
}
|
|
|
|
return pops;
|
|
|
|
}
|
|
|
|
|
2004-11-18 23:38:08 +01:00
|
|
|
static inline const struct pci_bus_operations *ops_pci_bus(struct bus *bus)
|
|
|
|
{
|
|
|
|
const struct pci_bus_operations *bops;
|
|
|
|
bops = 0;
|
|
|
|
if (bus && bus->dev && bus->dev->ops) {
|
|
|
|
bops = bus->dev->ops->ops_pci_bus;
|
|
|
|
}
|
If no pci access method has been set for the device tree so far (e.g.
during early coreboot_ram), pci_{read,write}_config{8,16,32} will die().
This patch changes pci_{read,write}_config{8,16,32} to use the existing
PCI access method autodetection infrastructure instead of die()ing.
Until r4340, any usage of pci_{read,write}_config{8,16,32} in
coreboot_ram before the device tree was set up resulted in either a
silent hang or a NULL pointer dereference. I changed the code in r4340
to die() properly with a loud error message. That still was not perfect,
but at least it allowed people to see why their new ports died.
Still, die() is not something developers like to see, and thus a patch
to automatically pick a sensible default instead of dying was created.
Of course, handling PCI access method selection automatically for
fallback purposes has certain limitations before the device tree is set
up. We only check if conf1 works and use conf2 as fallback. No further
tests are done.
This patch enables cleanups and readability improvements in early
coreboot_ram code:
Without this patch:
dword = pci_cf8_conf1.read32(&pbus, sm_dev->bus->secondary,
sm_dev->path.pci.devfn, 0x64);
With this patch:
dword = pci_read_config32(sm_dev, 0x64);
Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>
Acked-by: Peter Stuge <peter@stuge.se>
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@4646 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
2009-09-22 02:09:41 +02:00
|
|
|
if (!bops)
|
|
|
|
bops = pci_remember_direct();
|
2004-11-18 23:38:08 +01:00
|
|
|
return bops;
|
|
|
|
}
|
|
|
|
|
2011-02-03 10:14:40 +01:00
|
|
|
unsigned mainboard_pci_subsystem_vendor_id(struct device *dev);
|
|
|
|
unsigned mainboard_pci_subsystem_device_id(struct device *dev);
|
|
|
|
|
2003-04-24 08:25:08 +02:00
|
|
|
#endif /* PCI_H */
|