switch-coreboot/include/device/device.h
Stefan Reinauer 6869f4a129 new device model from Ron
This tree shows the new model. It demonstrates the constructor array
in use, for devices that are and are not specified in the dts. It
introduces a new generic structure, device_id, analogous to
device_path, which can describe all the types of device IDs we have.
It shows a way to set up arrays of structs, in the dts, for the
constructors, so we avoid ldscript hacks.

Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
Acked-by: Stefan Reinauer <stepan@coresystems.de>



git-svn-id: svn://coreboot.org/repository/LinuxBIOSv3@233 f3766cd6-281f-0410-b1cd-43a5c92072e9
2007-03-10 15:55:41 +00:00

278 lines
8.5 KiB
C

/*
* This file is part of the LinuxBIOS project.
* Copyright (C) 2007 Ronald G. Minnich <rminnich@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef DEVICE_H
#define DEVICE_H
#include <arch/types.h>
#include <device/resource.h>
#include <device/path.h>
#define DEVICE_ID_MAX 64
enum device_id_type {
DEVICE_ID_NONE = 0,
DEVICE_ID_ROOT,
DEVICE_ID_PCI,
DEVICE_ID_PNP,
DEVICE_ID_I2C,
DEVICE_ID_APIC,
DEVICE_ID_PCI_DOMAIN,
DEVICE_ID_APIC_CLUSTER,
DEVICE_ID_CPU,
DEVICE_ID_CPU_BUS,
};
struct device;
struct pci_operations;
struct pci_bus_operations;
struct smbus_bus_operations;
struct bus;
struct pci_domain_id
{
u16 vendor, device;
};
struct pci_id
{
u16 vendor, device;
};
struct pnp_id
{
u32 device;
};
struct i2c_id
{
u32 id;
};
struct apic_id
{
u16 vendor, device;
};
struct apic_cluster_id
{
u16 vendor, device;
};
struct cpu_id
{
u32 cpuid[3];
};
struct cpu_bus_id
{
u16 vendor, device;
};
struct device_id {
enum device_id_type type;
union {
struct pci_id pci;
struct pnp_id pnp;
struct i2c_id i2c;
struct apic_id apic;
struct pci_domain_id pci_domain;
struct apic_cluster_id apic_cluster;
struct cpu_id cpu;
struct cpu_bus_id cpu_bus;
} u;
};
struct constructor {
struct device_id id;
struct device_operations *ops;
};
struct device_operations {
/* for now, we leave these, since they seem generic */
void (*set_link)(struct device * dev, unsigned int link);
void (*reset_bus)(struct bus *bus);
/* a constructor. The constructor for a given device is defined in the device source file.
* When is this called? Not for the static tree. When the scan bus code finds a new device, it must
* create it and insert it into the device tree. To do this, it calls a device constructor.
* The set of all device constructors is concatenated into the constructors array of structures via the usual
* gcc hack of naming a segment.
* The dev_constructor code in device.c iterates over the constructors array.
* A match consists of a path type, a vendor (which may be ignored if the constructo vendor value is 0),
* and a device id.
* When it finds a match, the dev_constructor calls the
* function constructors->constructor(constructors->constructor) and a new device is created.
*/
struct device *(*constructor)(struct constructor *);
/* set device ops */
void (*phase1_set_device_operations)(struct device *dev);
/* phase 2 is for any magic you have to do before the busses are scanned */
void (*phase2_setup_scan_bus)(struct device * dev);
/* phase 3 is for scanning the bus, if needed. */
void (*phase3_enable_scan)(struct device *dev);
unsigned int (*phase3_scan)(struct device * bus, unsigned int max);
/* typically used by phase4 */
/* again, if we never use this anywhere else, we may change the names */
void (*phase4_read_resources)(struct device * dev);
void (*phase4_set_resources)(struct device * dev);
/* some devices need to be enabled to scan, then disabled again. */
/* this function enables/disables according the value of 'enabled' in the device*/
void (*phase4_enable_disable)(struct device * dev);
/* phase 5: enable devices */
void (*phase5_enable_resources)(struct device * dev);
/* phase 6: any post-setup device initialization that might be needed */
void (*phase6_init)(struct device * dev);
const struct pci_operations *ops_pci;
const struct smbus_bus_operations *ops_smbus_bus;
const struct pci_bus_operations *ops_pci_bus;
};
struct bus {
struct device * dev; /* This bridge device */
struct device * children; /* devices behind this bridge */
unsigned bridge_ctrl; /* Bridge control register */
unsigned char link; /* The index of this link */
unsigned char secondary; /* secondary bus number */
unsigned char subordinate; /* max subordinate bus number */
unsigned char cap; /* PCi capability offset */
unsigned reset_needed : 1;
unsigned disable_relaxed_ordering : 1;
};
#define MAX_RESOURCES 12
#define MAX_LINKS 8
/*
* There is one device structure for each slot-number/function-number
* combination:
*/
struct device {
struct bus * bus; /* bus this device is on, for bridge
* devices, it is the up stream bus */
struct device * sibling; /* next device on this bus */
struct device * next; /* chain of all devices */
struct device_path path;
char * dtsname; /* the name from the dts */
unsigned vendor;
unsigned device;
unsigned int class; /* 3 bytes: (base,sub,prog-if) */
unsigned int hdr_type; /* PCI header type */
unsigned int enabled : 1; /* set if we should enable the device */
unsigned int initialized : 1; /* set if we have initialized the device */
unsigned int have_resources : 1; /* Set if we have read the devices resources */
unsigned int on_mainboard : 1;
unsigned long rom_address;
u8 command;
/* Base registers for this device. I/O, MEM and Expansion ROM */
struct resource resource[MAX_RESOURCES];
unsigned int resources;
/* link are (down sream) buses attached to the device, usually a leaf
* device with no children have 0 buses attached and a bridge has 1 bus
*/
struct bus link[MAX_LINKS];
/* number of buses attached to the device */
unsigned int links;
struct device_operations *ops;
void *device_configuration;
};
extern struct device dev_root; /* root bus */
extern struct device *all_devices; /* list of all devices */
/* Generic device interface functions */
struct constructor *find_constructor(struct device_id *id);
struct device * alloc_dev(struct bus *parent, struct device_path *path, struct device_id *id);
void dev_enumerate(void);
void dev_configure(void);
void dev_enable(void);
void dev_initialize(void);
void dev_optimize(void);
/* Generic device helper functions */
int reset_bus(struct bus *bus);
unsigned int scan_bus(struct device *bus, unsigned int max);
void compute_allocate_resource(struct bus *bus, struct resource *bridge,
unsigned long type_mask, unsigned long type);
void assign_resources(struct bus *bus);
void enable_resources(struct device *dev);
void enumerate_static_device(void);
void enumerate_static_devices(void);
const char *dev_path(struct device * dev);
const char *dev_id_string(struct device_id *id);
const char *bus_path(struct bus *bus);
void dev_set_enabled(struct device * dev, int enable);
void disable_children(struct bus *bus);
/* Helper functions */
struct device * find_dev_path(struct bus *parent, struct device_path *path);
struct device * alloc_find_dev(struct bus *parent, struct device_path *path, struct device_id *id);
struct device * dev_find_device (unsigned int vendor, unsigned int device, struct device * from);
struct device * dev_find_class (unsigned int class, struct device * from);
struct device * dev_find_slot (unsigned int bus, unsigned int devfn);
struct device * dev_find_slot_on_smbus (unsigned int bus, unsigned int addr);
struct device *default_device_constructor(struct constructor *constructor);
/* Rounding for boundaries.
* Due to some chip bugs, go ahead and roung IO to 16
*/
#define DEVICE_IO_ALIGN 16
#define DEVICE_MEM_ALIGN 4096
extern struct device_operations default_dev_ops_root;
extern int id_eq(struct device_id *id1, struct device_id *id2);
void root_dev_read_resources(struct device * dev);
void root_dev_set_resources(struct device * dev);
unsigned int scan_static_bus(struct device * bus, unsigned int max);
void enable_childrens_resources(struct device * dev);
void root_dev_enable_resources(struct device * dev);
unsigned int root_dev_scan_bus(struct device * root, unsigned int max);
void root_dev_init(struct device * dev);
void dev_init(void);
void dev_phase1(void);
void dev_phase2(void);
void dev_root_phase3(void);
unsigned int dev_phase3_scan(struct device * busdevice, unsigned int max);
void dev_phase4(void);
void dev_root_phase5(void);
void dev_phase6(void);
void phase4_assign_resources(struct bus *bus);
unsigned int dev_phase3(struct device * bus, unsigned int max);
void dev_phase5(struct device *dev);
#endif /* DEVICE_H */