Some serious changes to get qemu working with pci.

Also added comments. 

A big change is in the dts. In OFW trees, the hierarchy seems to be:
/root/cpu/northbridge 
          south
          other pci

note that the north is in the hierarchy under the south. This hierarchy
makes no sense on systems with a shared frontside bus, or at least I
don't see how it can. In those systems, it's easier to think about 
the CPUs AND northbridges as children of the front side bus. 

in LinuxBIOS, it has always been this:
/root/cpu/whatever
/root/northbridge/
                  south
                  other pci

There have been many discussions over how it ought to be, for 8 years
now, and we've always come back to how LB does it. So I have changed the 
dts for qemu for now to match LB's way of doing things. Note that the
new system is flexible enough that, on K8, we CAN do things as above:
/cpu@0/amd8knorthbridge/etc.
/cpu@1/amd8knorthbridge/etc.

But on qemu, for now, the root is the mainboard, and the CPU and
northbridge are siblings. 

I've added some informational printks, cleaned up pci_ops, and done
other things so that it builds and all seems to work -- until it hangs
hard in enumeration in i440bx ...

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



git-svn-id: svn://coreboot.org/repository/LinuxBIOSv3@160 f3766cd6-281f-0410-b1cd-43a5c92072e9
This commit is contained in:
Ronald G. Minnich 2007-02-28 19:17:59 +00:00
commit b520f3201e
9 changed files with 68 additions and 11 deletions

View file

@ -647,11 +647,16 @@ unsigned int dev_phase3_scan(struct device * busdevice, unsigned int max)
!busdevice->ops ||
!busdevice->ops->phase3_scan)
{
printk(BIOS_INFO, "%s: busdevice %p enabled %d ops %p\n" ,
busdevice, busdevice ? busdevice->enabled : NULL,
busdevice ? busdevice->ops : NULL);
printk(BIOS_INFO, "%s: can not scan from here, returning %d\n", __FUNCTION__, max);
return max;
}
do_phase3 = 1;
while(do_phase3) {
int link;
printk(BIOS_INFO, "%s: scanning %s\n", __FUNCTION__, dev_path(busdevice));
new_max = busdevice->ops->phase3_scan(busdevice, max);
do_phase3 = 0;
for(link = 0; link < busdevice->links; link++) {
@ -665,6 +670,7 @@ unsigned int dev_phase3_scan(struct device * busdevice, unsigned int max)
}
}
post_code(0x4e);
printk(BIOS_INFO, "%s: returning %d\n", __FUNCTION__, max);
return new_max;
}

View file

@ -784,6 +784,8 @@ static void set_pci_ops(struct device *dev)
return;
}
#warning "need to fix this leftover PCI bogosity from V2"
#if 0
/* Look through the list of setup drivers and find one for
* this pci device
*/
@ -799,7 +801,7 @@ static void set_pci_ops(struct device *dev)
return;
}
}
#endif
/* If I don't have a specific driver use the default operations */
switch(dev->hdr_type & 0x7f) { /* header type */
case PCI_HEADER_TYPE_NORMAL: /* standard header */
@ -851,8 +853,8 @@ static struct device *pci_scan_get_dev(struct device **list, unsigned int devfn)
dev = 0;
for(; *list; list = &(*list)->sibling) {
if ((*list)->path.type != DEVICE_PATH_PCI) {
printk(BIOS_ERR,"child %s not a pci device\n",
dev_path(*list));
printk(BIOS_ERR,"%s: child %s not a pci device: it's type %d\n", __FUNCTION__,
dev_path(*list), (*list)->path.type);
continue;
}
if ((*list)->path.u.pci.devfn == devfn) {

View file

@ -15,10 +15,12 @@
*/
#include <console/console.h>
#include <device/device.h>
#include <arch/pciconf.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <device/pci_ops.h>
#include <arch/types.h>
static struct bus *get_pbus(struct device * dev)
{

View file

@ -98,7 +98,7 @@ unsigned int scan_static_bus(struct device * busdevice, unsigned int max)
struct device * child;
unsigned link;
printk(BIOS_SPEW, "%s for %s\n", __func__, dev_path(busdevice));
printk(BIOS_INFO, "%s for %s\n", __func__, dev_path(busdevice));
for(link = 0; link < busdevice->links; link++) {
/* for smbus bus enumerate */
@ -127,12 +127,12 @@ unsigned int scan_static_bus(struct device * busdevice, unsigned int max)
for(child = busdevice->link[link].children; child; child = child->sibling) {
if (!child->ops || !child->ops->phase3_scan)
continue;
printk(BIOS_SPEW, "%s scanning...\n", dev_path(child));
printk(BIOS_INFO, "%s scanning...\n", dev_path(child));
max = dev_phase3_scan(child, max);
}
}
printk(BIOS_SPEW, "%s for %s done\n", __func__, dev_path(busdevice));
printk(BIOS_INFO, "%s for %s done\n", __func__, dev_path(busdevice));
return max;
}

View file

@ -20,11 +20,11 @@
/* Safe for inclusion in assembly */
#ifndef MAXIMUM_CONSOLE_LOGLEVEL
#define MAXIMUM_CONSOLE_LOGLEVEL 8
#define MAXIMUM_CONSOLE_LOGLEVEL 9
#endif
#ifndef DEFAULT_CONSOLE_LOGLEVEL
#define DEFAULT_CONSOLE_LOGLEVEL 8 /* anything MORE serious than BIOS_SPEW */
#define DEFAULT_CONSOLE_LOGLEVEL 9 /* anything MORE serious than BIOS_SPEW */
#endif
#ifndef ASM_CONSOLE_LOGLEVEL

View file

@ -0,0 +1,29 @@
/*
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 ARCH_I386_PCI_OPS_H
#define ARCH_I386_PCI_OPS_H
const struct pci_bus_operations pci_cf8_conf1;
const struct pci_bus_operations pci_cf8_conf2;
#if MMCONF_SUPPORT==1
const struct pci_bus_operations pci_ops_mmconf;
#endif
void pci_set_method(struct device * dev);
#endif /* ARCH_I386_PCI_OPS_H */

View file

@ -1,3 +1,19 @@
/*
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 _SWAB_H
#define _SWAB_H

View file

@ -28,11 +28,13 @@
#include "i440bx.h"
/* This is the starting point. */
struct device_operations i440bxemulation_pcidomainops;
static void i440bxemulation_enable_dev(struct device *dev)
{
printk(BIOS_INFO, "%s: \n", __FUNCTION__);
/* Set the operations if it is a special bus type. */
/* just a test here. ... we don't want to do this in real life */
dev->ops = &i440bxemulation_pcidomainops;
/* Set the operations if it is a special bus type */
/*
if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) {
dev->ops = &pci_domain_ops;

View file

@ -538,7 +538,7 @@ static void linuxbios_emit_special(FILE *e, struct node *tree)
}
if (tree->next_sibling)
fprintf(f, "\t.sibling = dev_%s;\n", tree->next_sibling->label);
fprintf(f, "\t.sibling = &dev_%s,\n", tree->next_sibling->label);
/* now do we do next? */
/* this will need to do a bus for every child. And, below, we're going to need to find which bus we're on*/
/* for now, let's keep it to the minimum that will work, while we see if we like this. */