mirror of
https://github.com/fail0verflow/switch-coreboot.git
synced 2025-05-04 01:39:18 -04:00
This started out as a trivial change and turned into a big change. This
code boots and works on qemu and alix1c. It represents a huge change and a huge improvement. There are a few fixes left to do, which will come once this is in. This change started out easy: get the device IDs OUT of the the dts, and into one place. We decided the device IDs should be in the constructors ONLY. To make a long story short, that just did not work out, and it revealed a flaw in the design. The result? - no more ids in the various dts files. - the constructor struct is gone -- one less struct, nobody liked the name anyway - the device_operations struct now includes the device id. - constructor property no longer used; use device_operations instead. - lpc replaced with ioport All the changes below stem from this "simple" change. I am finding this new structure much easier to work with. I hope we're done on this for real, however! TODO: 1. Change limitation in dtc that makes it hard to use hex in pci@ notation. Now for the bad news. Sometime today, interrupts or io or something stopped working between r596 and r602 -- but I did no commits at that point. So something has gone wrong, but I don't think it's this stuff. I did try a build of HEAD, and it fails really, really badly. Much more badly than this fails, so I think this commit is only going to improve things. It does work fine on qemu, fails on alix1c, so I suspect one of today's "clean up commits" broke something. Signed-off-by: Ronald G. Minnich <rminnich@gmail.com> Acked-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net> git-svn-id: svn://coreboot.org/repository/coreboot-v3@603 f3766cd6-281f-0410-b1cd-43a5c92072e9
This commit is contained in:
parent
7980349f4f
commit
f7ad196c0a
20 changed files with 169 additions and 197 deletions
|
@ -73,6 +73,14 @@ static void lx_init(struct device *dev)
|
|||
printk(BIOS_SPEW, "CPU lx_init DONE\n");
|
||||
};
|
||||
|
||||
/**
|
||||
* Device operations for the CPU.
|
||||
*
|
||||
* Later, we might need to change it to use a different phase3_scan, and
|
||||
* match on a CPU ID. However, CPU IDs are known to be kind of weird,
|
||||
* depending on date manufactured they can be all over the place (the Geode
|
||||
* alone has had 3 vendors!) so we will have to be careful.
|
||||
*/
|
||||
/**
|
||||
* The only operations currently set up are the phase 6. We might, however,
|
||||
* set up an op in phase3_scan to get the cpuinfo into a struct for all to
|
||||
|
@ -83,25 +91,11 @@ static void lx_init(struct device *dev)
|
|||
* in multiple CPU files and use the device ID, at scan time, to pick which
|
||||
* one is used. There is a lot of flexibility here!
|
||||
*/
|
||||
static const struct device_operations geodelx_cpuops = {
|
||||
.constructor = default_device_constructor,
|
||||
.phase3_scan = NULL,
|
||||
.phase6_init = lx_init,
|
||||
};
|
||||
|
||||
/**
|
||||
* This is a constructor for a CPU.
|
||||
*
|
||||
* Later, we might need to change it to use a different phase3_scan, and
|
||||
* match on a CPU ID. However, CPU IDs are known to be kind of weird,
|
||||
* depending on date manufactured they can be all over the place (the Geode
|
||||
* alone has had 3 vendors!) so we will have to be careful.
|
||||
*/
|
||||
const struct constructor geodelx_constructors[] = {
|
||||
struct device_operations geodelx_cpuops = {
|
||||
{.id = {.type = DEVICE_ID_PCI,
|
||||
/* TODO: This is incorrect, these are _not_ PCI IDs! */
|
||||
.u = {.pci = {.vendor = X86_VENDOR_AMD,.device = 0x05A2}}},
|
||||
.ops = &geodelx_cpuops},
|
||||
|
||||
{.ops = 0},
|
||||
.ops = &geodelx_cpuops} .constructor = default_device_constructor,
|
||||
.phase3_scan = NULL,
|
||||
.phase6_init = lx_init,
|
||||
};
|
||||
|
|
|
@ -99,37 +99,36 @@ static struct device *new_device(void)
|
|||
* Initialize device->ops of a newly allocated device structure.
|
||||
*
|
||||
* @param dev Pointer to the newly created device structure.
|
||||
* @param constructor A pointer to a struct constructor.
|
||||
* @param ops Pointer to device_operations
|
||||
*/
|
||||
void default_device_constructor(struct device *dev, struct constructor *constructor)
|
||||
void default_device_constructor(struct device *dev, struct device_operations *ops)
|
||||
{
|
||||
printk(BIOS_DEBUG, "default device constructor called\n");
|
||||
dev->ops = constructor->ops;
|
||||
dev->ops = ops;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a path, locate the constructor for it from all_constructors.
|
||||
* Given a path, locate the device_operations for it from all_device_operations..
|
||||
*
|
||||
* @param path Path to the device to be created.
|
||||
* @return Pointer to the constructor or 0, if none found.
|
||||
* @return Pointer to the ops or 0, if none found.
|
||||
* @see device_path
|
||||
*/
|
||||
struct constructor *find_constructor(struct device_id *id)
|
||||
struct device_operations *find_device_operations(struct device_id *id)
|
||||
{
|
||||
extern struct constructor *all_constructors[];
|
||||
struct constructor *c;
|
||||
extern struct device_operations *all_device_operations[];
|
||||
struct device_operations *c;
|
||||
int i;
|
||||
|
||||
for (i = 0; all_constructors[i]; i++) {
|
||||
printk(BIOS_SPEW, "%s: check all_constructors[i] %p\n",
|
||||
__func__, all_constructors[i]);
|
||||
for (c = all_constructors[i]; c->ops; c++) {
|
||||
printk(BIOS_SPEW, "%s: cons %p, cons id %s\n",
|
||||
__func__, c, dev_id_string(&c->id));
|
||||
if (id_eq(&c->id, id)) {
|
||||
printk(BIOS_SPEW, "%s: match\n", __func__);
|
||||
return c;
|
||||
}
|
||||
for (i = 0; all_device_operations[i]; i++) {
|
||||
printk(BIOS_SPEW, "%s: check all_device_operations[i] %p\n",
|
||||
__func__, all_device_operations[i]);
|
||||
c = all_device_operations[i];
|
||||
printk(BIOS_SPEW, "%s: cons %p, cons id %s\n",
|
||||
__func__, c, dev_id_string(&c->id));
|
||||
if (id_eq(&c->id, id)) {
|
||||
printk(BIOS_SPEW, "%s: match\n", __func__);
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -147,48 +146,56 @@ struct constructor *find_constructor(struct device_id *id)
|
|||
void dev_init(void)
|
||||
{
|
||||
struct device *dev;
|
||||
struct constructor *c;
|
||||
struct device_operations *c;
|
||||
|
||||
for (dev = all_devices; dev; dev = dev->next) {
|
||||
c = find_constructor(&dev->id);
|
||||
c = dev->ops;
|
||||
if (c)
|
||||
dev->id = c->id;
|
||||
/* note the difference from the constructor function below.
|
||||
* we are not allocating the device here, just setting the ops.
|
||||
* we are not allocating the device here, just setting the id.
|
||||
* We set the id here because we don't want to set it in the dts
|
||||
* as we used to. The user sees none of this work.
|
||||
*/
|
||||
if (c)
|
||||
dev->ops = c->ops;
|
||||
dev->ops = c;
|
||||
last_dev_p = &dev->next;
|
||||
}
|
||||
devcnt = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a path, find a constructor, and run it.
|
||||
* Given a device, find a constructor function and, if found, run it.
|
||||
*
|
||||
* Given a path, call find_constructor to find the constructor for it.
|
||||
* Call that constructor via constructor->ops->constructor, with itself as
|
||||
* a parameter; return the result.
|
||||
* Given a device, use the device id in the device to find a device_operations.
|
||||
* Call the device_operations->constructor, with itself as
|
||||
* a parameter; return the result. If there is no constructor,
|
||||
* then no constructor is run.
|
||||
*
|
||||
* @param dev Pointer to the newly created device structure.
|
||||
* @param path Path to the device to be created.
|
||||
* @see device_path
|
||||
*/
|
||||
void constructor(struct device *dev, struct device_id *id)
|
||||
void constructor(struct device *dev)
|
||||
{
|
||||
struct constructor *c;
|
||||
struct device_operations *c;
|
||||
|
||||
c = find_constructor(id);
|
||||
c = dev->ops;
|
||||
|
||||
if (!c)
|
||||
c = find_device_operations(&dev->id);
|
||||
|
||||
printk(BIOS_SPEW, "%s: constructor is %p\n", __func__, c);
|
||||
|
||||
if(c && c->ops) {
|
||||
if(c->ops->constructor)
|
||||
c->ops->constructor(dev, c);
|
||||
if(c) {
|
||||
if(c->constructor)
|
||||
c->constructor(dev, c);
|
||||
else
|
||||
default_device_constructor(dev, c);
|
||||
}
|
||||
else
|
||||
printk(BIOS_INFO, "No constructor called for %s.\n",
|
||||
dev_id_string(id));
|
||||
printk(BIOS_INFO, "No ops found and no constructor called for %s.\n",
|
||||
dev_id_string(&dev->id));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -254,7 +261,7 @@ struct device *alloc_dev(struct bus *parent, struct device_path *path,
|
|||
* so it gets the chance to overwrite the "inherited" values above
|
||||
*/
|
||||
|
||||
constructor(dev, devid);
|
||||
constructor(dev);
|
||||
|
||||
out:
|
||||
spin_unlock(&dev_lock);
|
||||
|
|
|
@ -236,9 +236,9 @@ const char *dev_path(struct device *dev)
|
|||
sprintf(buffer, "CPU_BUS: %02x",
|
||||
dev->path.u.cpu_bus.id);
|
||||
break;
|
||||
case DEVICE_PATH_LPC:
|
||||
sprintf(buffer, "LPC: %02x",
|
||||
dev->path.u.lpc.iobase);
|
||||
case DEVICE_PATH_IOPORT:
|
||||
sprintf(buffer, "IOPORT: %02x",
|
||||
dev->path.u.ioport.iobase);
|
||||
break;
|
||||
default:
|
||||
printk(BIOS_ERR, "%s: Unknown device path type: %d\n",
|
||||
|
|
|
@ -810,7 +810,7 @@ static struct device_operations *get_pci_bridge_ops(struct device *dev)
|
|||
*/
|
||||
static void set_pci_ops(struct device *dev)
|
||||
{
|
||||
struct constructor *c;
|
||||
struct device_operations *c;
|
||||
struct device_id id;
|
||||
|
||||
if (dev->ops) {
|
||||
|
@ -824,9 +824,9 @@ static void set_pci_ops(struct device *dev)
|
|||
/* Look through the list of setup drivers and find one for
|
||||
* this PCI device.
|
||||
*/
|
||||
c = find_constructor(&id);
|
||||
c = find_device_operations(&dev->id);
|
||||
if (c) {
|
||||
dev->ops = c->ops;
|
||||
dev->ops = c;
|
||||
printk(BIOS_SPEW, "%s id %s %sops\n",
|
||||
dev_path(dev), dev_id_string(&id),
|
||||
(dev->ops->phase3_scan ? "bus " : ""));
|
||||
|
|
|
@ -112,12 +112,12 @@ struct device_id {
|
|||
};
|
||||
|
||||
|
||||
struct constructor {
|
||||
struct device_id id;
|
||||
struct device_operations *ops;
|
||||
};
|
||||
|
||||
struct device_operations {
|
||||
/* the device id for this set of device operations.
|
||||
* In almost all cases, this is non-zero. For the
|
||||
* default_device_constructor, it's zero
|
||||
*/
|
||||
struct device_id id;
|
||||
/* for now, we leave these, since they seem generic */
|
||||
void (*set_link)(struct device * dev, unsigned int link);
|
||||
void (*reset_bus)(struct bus *bus);
|
||||
|
@ -136,7 +136,7 @@ struct device_operations {
|
|||
* constructors->constructor(constructors->constructor) and a new
|
||||
* device is created.
|
||||
*/
|
||||
void (*constructor)(struct device *, struct constructor *);
|
||||
void (*constructor)(struct device *, struct device_operations *);
|
||||
|
||||
/* set device ops */
|
||||
void (*phase1_set_device_operations)(struct device *dev);
|
||||
|
@ -195,6 +195,9 @@ struct device {
|
|||
struct device * next; /* chain of all devices */
|
||||
|
||||
struct device_path path;
|
||||
/* note there is a device id maintained here. This covers the special case
|
||||
* of default_device_operations, which has an id of zero.
|
||||
*/
|
||||
struct device_id id;
|
||||
char dtsname[MAX_DTSNAME_SIZE]; /* the name from the dts */
|
||||
u16 status;
|
||||
|
@ -237,7 +240,7 @@ extern struct device *all_devices; /* list of all devices */
|
|||
|
||||
|
||||
/* Generic device interface functions */
|
||||
struct constructor *find_constructor(struct device_id *id);
|
||||
struct device_operations *find_device_operations(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);
|
||||
|
@ -268,7 +271,7 @@ struct device *dev_find_pci_device(u16 vendor, u16 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);
|
||||
void default_device_constructor(struct device *dev, struct constructor *constructor);
|
||||
void default_device_constructor(struct device *dev, struct device_operations *constructor);
|
||||
|
||||
|
||||
/* Rounding for boundaries.
|
||||
|
|
|
@ -30,7 +30,7 @@ enum device_path_type {
|
|||
DEVICE_PATH_APIC_CLUSTER,
|
||||
DEVICE_PATH_CPU,
|
||||
DEVICE_PATH_CPU_BUS,
|
||||
DEVICE_PATH_LPC,
|
||||
DEVICE_PATH_IOPORT,
|
||||
};
|
||||
|
||||
struct pci_domain_path
|
||||
|
@ -81,7 +81,7 @@ struct cpu_bus_path
|
|||
unsigned id;
|
||||
};
|
||||
|
||||
struct lpc_path
|
||||
struct ioport_path
|
||||
{
|
||||
unsigned iobase;
|
||||
};
|
||||
|
@ -99,7 +99,7 @@ struct device_path {
|
|||
struct apic_cluster_path apic_cluster;
|
||||
struct cpu_path cpu;
|
||||
struct cpu_bus_path cpu_bus;
|
||||
struct lpc_path lpc;
|
||||
struct ioport_path ioport;
|
||||
} u;
|
||||
};
|
||||
|
||||
|
|
|
@ -21,15 +21,15 @@
|
|||
/{
|
||||
mainboard-vendor = "Emulation";
|
||||
mainboard-name = "QEMU x86";
|
||||
constructor = "qemuvga_constructors";
|
||||
device_operations = "qemuvga_pci_ops_dev";
|
||||
cpus {};
|
||||
domain@0 {
|
||||
/config/("northbridge/intel/i440bxemulation/dts");
|
||||
/config/("northbridge/intel/i440bxemulation/domain");
|
||||
bus@0 {
|
||||
pci@0,0 {
|
||||
};
|
||||
pci@1,0 {
|
||||
/config/("southbridge/intel/i82371eb/dts");
|
||||
/config/("southbridge/intel/i82371eb/ide");
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -43,7 +43,10 @@ static void setup_onboard(struct device *dev)
|
|||
init_pc_keyboard(0x60, 0x64, &conf);
|
||||
}
|
||||
|
||||
static const struct device_operations qemuvga_pci_ops_dev = {
|
||||
struct device_operations qemuvga_pci_ops_dev = {
|
||||
.id = {.type = DEVICE_ID_PCI,
|
||||
.u = {.pci = {.vendor = PCI_VENDOR_ID_CIRRUS,
|
||||
.device = PCI_DEVICE_ID_CIRRUS_5446}}},
|
||||
.constructor = default_device_constructor,
|
||||
.phase3_scan = 0,
|
||||
.phase4_read_resources = pci_dev_read_resources,
|
||||
|
@ -54,11 +57,3 @@ static const struct device_operations qemuvga_pci_ops_dev = {
|
|||
.ops_pci = &pci_dev_ops_pci,
|
||||
};
|
||||
|
||||
const struct constructor qemuvga_constructors[] = {
|
||||
{.id = {.type = DEVICE_ID_PCI,
|
||||
.u = {.pci = {.vendor = PCI_VENDOR_ID_CIRRUS,
|
||||
.device = PCI_DEVICE_ID_CIRRUS_5446}}},
|
||||
&qemuvga_pci_ops_dev},
|
||||
|
||||
{.ops = 0},
|
||||
};
|
||||
|
|
|
@ -22,26 +22,17 @@
|
|||
enabled;
|
||||
mainboard-vendor = "PC Engines";
|
||||
mainboard-name = "ALIX1.C";
|
||||
cpus {
|
||||
enabled;
|
||||
};
|
||||
apic {
|
||||
cpus { };
|
||||
apic@0 {
|
||||
/config/("northbridge/amd/geodelx/apic");
|
||||
enabled;
|
||||
};
|
||||
domain0 {
|
||||
domain@0 {
|
||||
/config/("northbridge/amd/geodelx/domain");
|
||||
enabled;
|
||||
pcidomain = "0";
|
||||
device0,0 {
|
||||
/config/("northbridge/amd/geodelx/pci");
|
||||
enabled;
|
||||
pcipath = "1,0";
|
||||
pci@1,0 {
|
||||
/config/("northbridge/amd/geodelx/pci");
|
||||
};
|
||||
southbridge {
|
||||
pci@15,0 {
|
||||
/config/("southbridge/amd/cs5536/dts");
|
||||
pcipath = "0xf,0";
|
||||
enabled;
|
||||
enable_ide = "1";
|
||||
/* Interrupt enables for LPC bus.
|
||||
* Each bit is an IRQ 0-15. */
|
||||
|
@ -54,7 +45,7 @@
|
|||
* See virtual PIC spec. */
|
||||
enable_gpio_int_route = "0x0D0C0700";
|
||||
};
|
||||
superio {
|
||||
ioport@46 {
|
||||
/config/("superio/winbond/w83627hf/dts");
|
||||
com1enable = "1";
|
||||
};
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
*/
|
||||
|
||||
{
|
||||
constructor = "geodelx_north_constructors";
|
||||
apicid = "PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LXBRIDGE";
|
||||
device_operations = "geodelx_north_apic";
|
||||
};
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
*/
|
||||
|
||||
{
|
||||
constructor = "geodelx_north_constructors";
|
||||
domainid = "PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LXBRIDGE";
|
||||
device_operations = "geodelx_north_domain";
|
||||
};
|
||||
|
||||
|
|
|
@ -300,7 +300,10 @@ static void cpu_bus_noop(struct device *dev)
|
|||
*/
|
||||
|
||||
/** Operations for when the northbridge is running a PCI domain. */
|
||||
static struct device_operations geodelx_pcidomain_ops = {
|
||||
struct device_operations geodelx_north_domain = {
|
||||
.id = {.type = DEVICE_ID_PCI_DOMAIN,
|
||||
.u = {.pci_domain = {.vendor = PCI_VENDOR_ID_AMD,
|
||||
.device = PCI_DEVICE_ID_AMD_LXBRIDGE}}},
|
||||
.constructor = default_device_constructor,
|
||||
.phase2_setup_scan_bus = geodelx_pci_domain_phase2,
|
||||
.phase3_scan = pci_domain_scan_bus,
|
||||
|
@ -312,7 +315,10 @@ static struct device_operations geodelx_pcidomain_ops = {
|
|||
};
|
||||
|
||||
/** Operations for when the northbridge is running an APIC cluster. */
|
||||
static struct device_operations geodelx_apic_ops = {
|
||||
struct device_operations geodelx_north_apic = {
|
||||
.id = {.type = DEVICE_ID_APIC_CLUSTER,
|
||||
.u = {.apic_cluster = {.vendor = PCI_VENDOR_ID_AMD,
|
||||
.device = PCI_DEVICE_ID_AMD_LXBRIDGE}}},
|
||||
.constructor = default_device_constructor,
|
||||
.phase3_scan = 0,
|
||||
.phase4_read_resources = cpu_bus_noop,
|
||||
|
@ -326,7 +332,10 @@ static struct device_operations geodelx_apic_ops = {
|
|||
/** Note that phase3 scan is done in the domain,
|
||||
* and MUST NOT be done here too
|
||||
*/
|
||||
static struct device_operations geodelx_pci_ops = {
|
||||
struct device_operations geodelx_north_pci = {
|
||||
.id = {.type = DEVICE_ID_PCI,
|
||||
.u = {.pci = {.vendor = PCI_VENDOR_ID_AMD,
|
||||
.device = PCI_DEVICE_ID_AMD_LXBRIDGE}}},
|
||||
.constructor = default_device_constructor,
|
||||
.phase3_scan = 0,
|
||||
.phase4_read_resources = pci_domain_read_resources,
|
||||
|
@ -335,29 +344,3 @@ static struct device_operations geodelx_pci_ops = {
|
|||
.phase6_init = geodelx_northbridge_init,
|
||||
.ops_pci_bus = &pci_cf8_conf1,
|
||||
};
|
||||
|
||||
/**
|
||||
* The constructor for the device.
|
||||
* Domain ops and APIC cluster ops and PCI device ops are different.
|
||||
*/
|
||||
struct constructor geodelx_north_constructors[] = {
|
||||
/* Northbridge running a PCI domain. */
|
||||
{.id = {.type = DEVICE_ID_PCI_DOMAIN,
|
||||
.u = {.pci_domain = {.vendor = PCI_VENDOR_ID_AMD,
|
||||
.device = PCI_DEVICE_ID_AMD_LXBRIDGE}}},
|
||||
.ops = &geodelx_pcidomain_ops},
|
||||
|
||||
/* Northbridge running an APIC cluster. */
|
||||
{.id = {.type = DEVICE_ID_APIC_CLUSTER,
|
||||
.u = {.apic_cluster = {.vendor = PCI_VENDOR_ID_AMD,
|
||||
.device = PCI_DEVICE_ID_AMD_LXBRIDGE}}},
|
||||
.ops = &geodelx_apic_ops},
|
||||
|
||||
/* Northbridge running a PCI device. */
|
||||
{.id = {.type = DEVICE_ID_PCI,
|
||||
.u = {.pci = {.vendor = PCI_VENDOR_ID_AMD,
|
||||
.device = PCI_DEVICE_ID_AMD_LXBRIDGE}}},
|
||||
.ops = &geodelx_pci_ops},
|
||||
|
||||
{.ops = 0},
|
||||
};
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
*/
|
||||
|
||||
{
|
||||
constructor = "geodelx_north_constructors";
|
||||
pciid = "PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LXBRIDGE";
|
||||
device_operations = "geodelx_north_pci";
|
||||
};
|
||||
|
||||
|
|
|
@ -20,6 +20,5 @@
|
|||
|
||||
{
|
||||
ramsize = "128";
|
||||
constructor = "i440bx_constructors";
|
||||
domainid = "0x8086, 0x7190";
|
||||
device_operations = "i440bx_domain";
|
||||
};
|
|
@ -53,7 +53,7 @@ static void pci_domain_set_resources(struct device *dev)
|
|||
struct device *mc_dev;
|
||||
u32 tolmk; /* Top of low mem, Kbytes. */
|
||||
int idx;
|
||||
struct northbridge_intel_i440bxemulation_dts_config *device_configuration =
|
||||
struct northbridge_intel_i440bxemulation_domain_config *device_configuration =
|
||||
dev->device_configuration;
|
||||
tolmk = device_configuration->ramsize * 1024;
|
||||
mc_dev = dev->link[0].children;
|
||||
|
@ -66,7 +66,9 @@ static void pci_domain_set_resources(struct device *dev)
|
|||
|
||||
/* Here are the operations for when the northbridge is running a PCI domain. */
|
||||
/* See mainboard/emulation/qemu-x86 for an example of how these are used. */
|
||||
struct device_operations i440bxemulation_pcidomainops = {
|
||||
struct device_operations i440bx_domain = {
|
||||
.id = {.type = DEVICE_ID_PCI_DOMAIN,
|
||||
.u = {.pci_domain = {.vendor = 0x8086,.device = 0x7190}}},
|
||||
.constructor = default_device_constructor,
|
||||
.phase3_scan = pci_domain_scan_bus,
|
||||
.phase4_read_resources = pci_domain_read_resources,
|
||||
|
@ -76,15 +78,3 @@ struct device_operations i440bxemulation_pcidomainops = {
|
|||
.ops_pci_bus = &pci_cf8_conf1,
|
||||
|
||||
};
|
||||
|
||||
/* The constructor for the device. */
|
||||
/* The plain PCI device uses the standard PCI operations. */
|
||||
struct constructor i440bx_constructors[] = {
|
||||
{.id = {.type = DEVICE_ID_PCI_DOMAIN,
|
||||
.u = {.pci_domain = {.vendor = 0x8086,.device = 0x7190}}},
|
||||
.ops = &i440bxemulation_pcidomainops},
|
||||
{.id = {.type = DEVICE_ID_PCI,
|
||||
.u = {.pci = {.vendor = 0x8086,.device = 0x7190}}},
|
||||
.ops = &default_pci_ops_bus},
|
||||
{.ops = 0},
|
||||
};
|
||||
|
|
|
@ -634,7 +634,10 @@ static void cs5536_pci_dev_enable_resources(struct device *dev)
|
|||
printk(BIOS_SPEW, "cs5536: %s() Exit\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
static struct device_operations southbridge_ops = {
|
||||
struct device_operations cs5536_ops = {
|
||||
.id = {.type = DEVICE_ID_PCI,
|
||||
.u = {.pci = {.vendor = PCI_VENDOR_ID_AMD,
|
||||
.device = PCI_DEVICE_ID_AMD_CS5536_ISA}}},
|
||||
.constructor = default_device_constructor,
|
||||
.phase3_scan = scan_static_bus,
|
||||
.phase4_read_resources = pci_dev_read_resources,
|
||||
|
@ -643,11 +646,3 @@ static struct device_operations southbridge_ops = {
|
|||
.phase6_init = southbridge_init,
|
||||
};
|
||||
|
||||
struct constructor cs5536_constructors[] = {
|
||||
{.id = {.type = DEVICE_ID_PCI,
|
||||
.u = {.pci = {.vendor = PCI_VENDOR_ID_AMD,
|
||||
.device = PCI_DEVICE_ID_AMD_CS5536_ISA}}},
|
||||
.ops = &southbridge_ops},
|
||||
|
||||
{.ops = 0},
|
||||
};
|
||||
|
|
|
@ -19,8 +19,7 @@
|
|||
*/
|
||||
|
||||
{
|
||||
constructor = "cs5536_constructors";
|
||||
pciid = "PCI_VENDOR_ID_AMD,PCI_DEVICE_ID_AMD_CS5536_ISA";
|
||||
device_operations = "cs5536_ops";
|
||||
|
||||
/* Interrupt enables for LPC bus. Each bit is an IRQ 0-15. */
|
||||
lpc_serirq_enable = "0";
|
||||
|
|
|
@ -83,7 +83,9 @@ static void i82371eb_acpi_init(struct device *dev)
|
|||
}
|
||||
|
||||
/* You can override or extend each operation as needed for the device. */
|
||||
static struct device_operations i82371eb_isa_ops_dev = {
|
||||
struct device_operations i82371eb_isa = {
|
||||
.id = {.type = DEVICE_ID_PCI,
|
||||
.u = {.pci = {.vendor = 0x8086,.device = 0x7000}}},
|
||||
.constructor = default_device_constructor,
|
||||
.phase3_scan = 0,
|
||||
.phase4_read_resources = pci_dev_read_resources,
|
||||
|
@ -94,7 +96,9 @@ static struct device_operations i82371eb_isa_ops_dev = {
|
|||
.ops_pci = &pci_dev_ops_pci,
|
||||
};
|
||||
|
||||
static struct device_operations i82371eb_ide_ops_dev = {
|
||||
struct device_operations i82371eb_ide = {
|
||||
.id = {.type = DEVICE_ID_PCI,
|
||||
.u = {.pci = {.vendor = 0x8086,.device = 0x7010}}},
|
||||
.constructor = default_device_constructor,
|
||||
.phase3_scan = 0,
|
||||
.phase4_read_resources = pci_dev_read_resources,
|
||||
|
@ -105,7 +109,9 @@ static struct device_operations i82371eb_ide_ops_dev = {
|
|||
.ops_pci = &pci_dev_ops_pci,
|
||||
};
|
||||
|
||||
static struct device_operations i82371eb_acpi_ops_dev = {
|
||||
struct device_operations i82371eb_acpi = {
|
||||
.id = {.type = DEVICE_ID_PCI,
|
||||
.u = {.pci = {.vendor = 0x8086,.device = 0x7113}}},
|
||||
.constructor = default_device_constructor,
|
||||
.phase3_scan = 0,
|
||||
.phase4_read_resources = pci_dev_read_resources,
|
||||
|
@ -115,16 +121,3 @@ static struct device_operations i82371eb_acpi_ops_dev = {
|
|||
.phase6_init = i82371eb_acpi_init,
|
||||
.ops_pci = &pci_dev_ops_pci,
|
||||
};
|
||||
|
||||
struct constructor i82371eb_constructors[] = {
|
||||
{.id = {.type = DEVICE_ID_PCI,
|
||||
.u = {.pci = {.vendor = 0x8086,.device = 0x7000}}},
|
||||
&i82371eb_isa_ops_dev},
|
||||
{.id = {.type = DEVICE_ID_PCI,
|
||||
.u = {.pci = {.vendor = 0x8086,.device = 0x7010}}},
|
||||
&i82371eb_ide_ops_dev},
|
||||
{.id = {.type = DEVICE_ID_PCI,
|
||||
.u = {.pci = {.vendor = 0x8086,.device = 0x7113}}},
|
||||
&i82371eb_acpi_ops_dev},
|
||||
{.ops = 0},
|
||||
};
|
||||
|
|
|
@ -21,5 +21,5 @@
|
|||
{
|
||||
ide0_enable = "0";
|
||||
ide1_enable = "0";
|
||||
constructor = "i82371eb_constructors";
|
||||
device_operations = "i82371eb_ide";
|
||||
};
|
|
@ -555,8 +555,8 @@ static void coreboot_emit_special(FILE *e, struct node *tree)
|
|||
fprintf(f, "\t.path = {.type=DEVICE_PATH_PCI,.u={.pci={ .devfn = PCI_DEVFN(%s)}}},\n",
|
||||
path);
|
||||
}
|
||||
if (!strncmp(tree->name, "lpc", 3)){
|
||||
fprintf(f, "\t.path = {.type=DEVICE_PATH_SUPERIO,.u={.superio={.iobase=%s}}},\n",
|
||||
if (!strncmp(tree->name, "ioport", 3)){
|
||||
fprintf(f, "\t.path = {.type=DEVICE_PATH_IOPORT,.u={.ioport={.iobase=%s}}},\n",
|
||||
path);
|
||||
}
|
||||
}
|
||||
|
@ -575,17 +575,11 @@ static void coreboot_emit_special(FILE *e, struct node *tree)
|
|||
*/
|
||||
/* get the properties out that are generic device props */
|
||||
for_each_config(tree, prop) {
|
||||
if (streq(prop->name, "domainid")){
|
||||
fprintf(f, "\t.id = {.type=DEVICE_ID_PCI_DOMAIN,.u={.pci_domain={ %s }}},\n",
|
||||
prop->val.val);
|
||||
if (streq(prop->name, "constructor")){
|
||||
fprintf(f, "\t.ops = &%s,\n", prop->val.val);
|
||||
}
|
||||
if (streq(prop->name, "pciid")){
|
||||
fprintf(f, "\t.id = {.type=DEVICE_ID_PCI,.u={.pci={ %s }}},\n",
|
||||
prop->val.val);
|
||||
}
|
||||
if (streq(prop->name, "apicid")){
|
||||
fprintf(f, "\t.id = {.type=DEVICE_ID_APIC,.u={.pci={ %s }}},\n",
|
||||
prop->val.val);
|
||||
if (streq(prop->name, "device_operations")){
|
||||
fprintf(f, "\t.ops = &%s,\n", prop->val.val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -718,7 +712,7 @@ static void flatten_tree_emit_includes(struct node *tree, struct emitter *emit,
|
|||
|
||||
}
|
||||
|
||||
static void flatten_tree_emit_constructors(struct node *tree, struct emitter *emit,
|
||||
static void flatten_tree_emit_device_operations(struct node *tree, struct emitter *emit,
|
||||
void *etarget, struct data *strbuf,
|
||||
struct version_info *vi)
|
||||
{
|
||||
|
@ -727,18 +721,32 @@ static void flatten_tree_emit_constructors(struct node *tree, struct emitter *em
|
|||
/* find any/all properties with the name constructor */
|
||||
for_each_config(tree, prop) {
|
||||
if (streq(prop->name, "constructor")){
|
||||
printf("\t%s,\n", prop->val.val);
|
||||
fprintf(stderr, "LEFT OVER CONSTRUCTOR -- FIX ME\n");
|
||||
printf("\t&%s,\n", prop->val.val);
|
||||
}
|
||||
}
|
||||
|
||||
for_each_property(tree, prop) {
|
||||
if (streq(prop->name, "constructor")){
|
||||
printf("\t%s,\n", prop->val.val);
|
||||
printf("\t&%s,\n", prop->val.val);
|
||||
fprintf(stderr, "LEFT OVER CONSTRUCTOR -- FIX ME\n");
|
||||
}
|
||||
}
|
||||
|
||||
for_each_config(tree, prop) {
|
||||
if (streq(prop->name, "device_operations")){
|
||||
printf("\t&%s,\n", prop->val.val);
|
||||
}
|
||||
}
|
||||
|
||||
for_each_property(tree, prop) {
|
||||
if (streq(prop->name, "device_operations")){
|
||||
printf("\t&%s,\n", prop->val.val);
|
||||
}
|
||||
}
|
||||
|
||||
for_each_child(tree, child) {
|
||||
flatten_tree_emit_constructors(child, emit, etarget, strbuf, vi);
|
||||
flatten_tree_emit_device_operations(child, emit, etarget, strbuf, vi);
|
||||
}
|
||||
|
||||
|
||||
|
@ -774,6 +782,8 @@ static void flatten_tree_emit_structdecls(struct node *tree, struct emitter *emi
|
|||
seen_name_prop = 1;
|
||||
if (streq(prop->name, "constructor")) /* this is special */
|
||||
continue;
|
||||
if (streq(prop->name, "device_operations")) /* this is special */
|
||||
continue;
|
||||
cleanname = clean(prop->name, 0);
|
||||
fprintf(f, "\tu32 %s;\n", cleanname);
|
||||
free(cleanname);
|
||||
|
@ -790,13 +800,25 @@ static void flatten_tree_emit_structdecls(struct node *tree, struct emitter *emi
|
|||
for_each_config(tree, prop) {
|
||||
if (! streq(prop->name, "constructor")) /* this is special */
|
||||
continue;
|
||||
fprintf(f, "extern struct constructor %s[];\n", prop->val.val);
|
||||
fprintf(f, "extern struct device_operations %s;\n", prop->val.val);
|
||||
}
|
||||
|
||||
for_each_config(tree, prop) {
|
||||
if (! streq(prop->name, "device_operations")) /* this is special */
|
||||
continue;
|
||||
fprintf(f, "extern struct device_operations %s;\n", prop->val.val);
|
||||
}
|
||||
|
||||
for_each_property(tree, prop) {
|
||||
if (! streq(prop->name, "constructor")) /* this is special */
|
||||
continue;
|
||||
fprintf(f, "extern struct constructor %s[];\n", prop->val.val);
|
||||
fprintf(f, "extern struct device_operations %s;\n", prop->val.val);
|
||||
}
|
||||
|
||||
for_each_property(tree, prop) {
|
||||
if (! streq(prop->name, "device_operations")) /* this is special */
|
||||
continue;
|
||||
fprintf(f, "extern struct device_operations %s;\n", prop->val.val);
|
||||
}
|
||||
|
||||
for_each_property(tree, prop) {
|
||||
|
@ -805,6 +827,7 @@ static void flatten_tree_emit_structdecls(struct node *tree, struct emitter *emi
|
|||
fprintf(f, "extern struct device_operations %s;\n", prop->val.val);
|
||||
}
|
||||
|
||||
|
||||
for_each_child(tree, child) {
|
||||
flatten_tree_emit_structdecls(child, emit, etarget, strbuf, vi);
|
||||
}
|
||||
|
@ -849,6 +872,9 @@ static void flatten_tree_emit_structinits(struct node *tree, struct emitter *emi
|
|||
if (streq(configprop->name, "constructor")) /* this is special */
|
||||
continue;
|
||||
|
||||
if (streq(configprop->name, "device_operations")) /* this is special */
|
||||
continue;
|
||||
|
||||
for_each_property(tree, dtsprop) {
|
||||
if (streq(dtsprop->name,configprop->name)){
|
||||
emit->data(etarget, dtsprop);
|
||||
|
@ -1329,8 +1355,8 @@ void dt_to_coreboot(FILE *f, struct boot_info *bi, int version, int boot_cpuid_p
|
|||
if (code)
|
||||
fprintf(f, "%s\n", code);
|
||||
flatten_tree_emit_structinits(bi->dt, &coreboot_emitter, f, &strbuf, vi);
|
||||
fprintf(f, "struct constructor *all_constructors[] = {\n");
|
||||
flatten_tree_emit_constructors(bi->dt, &coreboot_emitter, f, &strbuf, vi);
|
||||
fprintf(f, "struct device_operations *all_device_operations[] = {\n");
|
||||
flatten_tree_emit_device_operations(bi->dt, &coreboot_emitter, f, &strbuf, vi);
|
||||
fprintf(f, "\t0\n};\n");
|
||||
data_free(strbuf);
|
||||
/* */
|
||||
|
|
Loading…
Add table
Reference in a new issue