Lots of changes here, build broken, but people need to see this.
renamed the phase3 etc. to stuff like phase3_scan, so you can get a
rought idea what it is. The names mean more.
adding pci_device and, at the same time, showing how we can get rid of
the really ugly stuff that crept in. note you can specify ops in the
dts, which avoids the need for hideous stuff like this:
static void enable_dev(struct device *dev)
{
/* Set the operations if it is a special bus type */
if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) {
dev->ops = &pci_domain_ops;
pci_set_method(dev);
}
else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) {
dev->ops = &cpu_bus_ops;
}
}
So that foolishness is gone.
added delay functions.
Note that we have include/lib.h, and define all the functions in there,
instead of in lots of fiddly includes.
Brought back the enable op, once I understood it; renamed it to
something that makes sense.
I'll be on a plane soon, will continue to work, but at least you can see
what's going on here.
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@139 f3766cd6-281f-0410-b1cd-43a5c92072e9
This commit is contained in:
parent
5274be0191
commit
7513bfdb03
13 changed files with 237 additions and 97 deletions
|
|
@ -108,8 +108,6 @@ $(obj)/stage0.init: $(STAGE0_OBJ)
|
|||
|
||||
STAGE2_LIB_OBJ = $(obj)/stage2.o $(obj)/clog2.o $(obj)/mem.o $(obj)/malloc.o \
|
||||
$(obj)/tables.o
|
||||
STAGE2_DEVICE_OBJ = $(obj)/device.o $(obj)/device_util.o \
|
||||
$(obj)/root_device.o
|
||||
STAGE2_ARCH_X86_OBJ = $(obj)/archtables.o $(obj)/linuxbios_table.o
|
||||
STAGE2_MAINBOARD_OBJ = $(obj)/mainboard.o
|
||||
STAGE2_DYNAMIC_OBJ = $(obj)/statictree.o
|
||||
|
|
|
|||
27
arch/x86/udelay_io.c
Normal file
27
arch/x86/udelay_io.c
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* This file is part of the LinuxBIOS project.
|
||||
*
|
||||
* Copyright (C) FIXME GET HISTORY
|
||||
*
|
||||
* 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; version 2 of the License.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
#include <arch/io.h>
|
||||
|
||||
void udelay(int usecs)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < usecs; i++)
|
||||
outb(i&0xff, 0x80);
|
||||
}
|
||||
|
||||
|
|
@ -21,3 +21,5 @@
|
|||
$(obj)/%.o: $(src)/device/%.c
|
||||
$(Q)$(CC) $(INITCFLAGS) -c $< -o $@
|
||||
|
||||
STAGE2_DEVICE_OBJ = $(obj)/device.o $(obj)/device_util.o \
|
||||
$(obj)/root_device.o $(obj)/pci_device.o $(obj)/pci_ops.o
|
||||
|
|
|
|||
|
|
@ -546,11 +546,11 @@ void dev_phase5(struct device *dev)
|
|||
printk(BIOS_ERR, "%s missing ops\n", dev_path(dev));
|
||||
return;
|
||||
}
|
||||
if (!dev->ops->phase5) {
|
||||
printk(BIOS_ERR, "%s ops are missing phase5\n", dev_path(dev));
|
||||
if (!dev->ops->phase5_enable_resources) {
|
||||
printk(BIOS_ERR, "%s ops are missing phase5_enable_resources\n", dev_path(dev));
|
||||
return;
|
||||
}
|
||||
dev->ops->phase5(dev);
|
||||
dev->ops->phase5_enable_resources(dev);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -637,7 +637,7 @@ void dev_phase2(void)
|
|||
*
|
||||
* @return The maximum bus number found, after scanning all subordinate busses
|
||||
*/
|
||||
unsigned int dev_phase3(struct device * busdevice, unsigned int max)
|
||||
unsigned int dev_phase3_scan(struct device * busdevice, unsigned int max)
|
||||
{
|
||||
unsigned int new_max;
|
||||
int do_phase3;
|
||||
|
|
@ -645,14 +645,14 @@ unsigned int dev_phase3(struct device * busdevice, unsigned int max)
|
|||
if ( !busdevice ||
|
||||
!busdevice->enabled ||
|
||||
!busdevice->ops ||
|
||||
!busdevice->ops->phase3)
|
||||
!busdevice->ops->phase3_scan)
|
||||
{
|
||||
return max;
|
||||
}
|
||||
do_phase3 = 1;
|
||||
while(do_phase3) {
|
||||
int link;
|
||||
new_max = busdevice->ops->phase3(busdevice, max);
|
||||
new_max = busdevice->ops->phase3_scan(busdevice, max);
|
||||
do_phase3 = 0;
|
||||
for(link = 0; link < busdevice->links; link++) {
|
||||
if (busdevice->link[link].reset_needed) {
|
||||
|
|
@ -705,11 +705,11 @@ void dev_root_phase3(void)
|
|||
printk(BIOS_ERR, "dev_root_phase3 missing 'ops' initialization\nPhase 3: Failed\n");
|
||||
return;
|
||||
}
|
||||
if (!root->ops->phase3) {
|
||||
if (!root->ops->phase3_scan) {
|
||||
printk(BIOS_ERR, "dev_root ops struct missing 'phase3' initialization in ops structure\nPhase 3: Failed");
|
||||
return;
|
||||
}
|
||||
subordinate = dev_phase3(root, 0);
|
||||
subordinate = dev_phase3_scan(root, 0);
|
||||
printk(BIOS_INFO, "Phase 3: done\n");
|
||||
}
|
||||
|
||||
|
|
@ -814,7 +814,7 @@ void dev_phase6(void)
|
|||
printk(BIOS_INFO, "Phase 6: Initializing devices...\n");
|
||||
for(dev = all_devices; dev; dev = dev->next) {
|
||||
if (dev->enabled && !dev->initialized &&
|
||||
dev->ops && dev->ops->phase6)
|
||||
dev->ops && dev->ops->phase6_init)
|
||||
{
|
||||
if (dev->path.type == DEVICE_PATH_I2C) {
|
||||
printk(BIOS_DEBUG, "Phase 6: smbus: %s[%d]->",
|
||||
|
|
@ -822,7 +822,7 @@ void dev_phase6(void)
|
|||
}
|
||||
printk(BIOS_DEBUG, "Phase 6: %s init\n", dev_path(dev));
|
||||
dev->initialized = 1;
|
||||
dev->ops->phase6(dev);
|
||||
dev->ops->phase6_init(dev);
|
||||
}
|
||||
}
|
||||
printk(BIOS_INFO, "Phase 6:Devices initialized\n");
|
||||
|
|
|
|||
|
|
@ -530,8 +530,8 @@ void dev_set_enabled(struct device * dev, int enable)
|
|||
return;
|
||||
}
|
||||
dev->enabled = enable;
|
||||
if (dev->ops && dev->ops->phase5) {
|
||||
dev->ops->phase5(dev);
|
||||
if (dev->ops && dev->ops->phase5_enable_resources) {
|
||||
dev->ops->phase5_enable_resources(dev);
|
||||
}
|
||||
else if (dev->chip_ops && dev->chip_ops->enable_dev) {
|
||||
dev->chip_ops->enable_dev(dev);
|
||||
|
|
|
|||
|
|
@ -28,15 +28,18 @@
|
|||
#include <console/console.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <bitops.h>
|
||||
#include <string.h>
|
||||
#include <arch/io.h>
|
||||
#include <device/device.h>
|
||||
#include <device/pci.h>
|
||||
#include <device/pci_ids.h>
|
||||
#include <part/hard_reset.h>
|
||||
#include <part/fallback_boot.h>
|
||||
#include <delay.h>
|
||||
#include <lib.h>
|
||||
#include <arch/io.h>
|
||||
#define CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT 0
|
||||
#define CONFIG_PCIX_PLUGIN_SUPPORT 0
|
||||
#define CONFIG_PCIEXP_PLUGIN_SUPPORT 0
|
||||
#define CONFGI_AGP_PLUGIN_SUPPORT 0
|
||||
#define CONFIG_CARDBUS_PLUGIN_SUPPORT 0
|
||||
#define CONFIG_AGP_PLUGIN_SUPPORT 0
|
||||
#if CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT == 1
|
||||
#include <device/hypertransport.h>
|
||||
#endif
|
||||
|
|
@ -101,7 +104,7 @@ uint32_t pci_moving_config32(struct device *dev, unsigned reg)
|
|||
return ones ^ zeroes;
|
||||
}
|
||||
|
||||
unsigned pci_find_next_capability(device_t dev, unsigned cap, unsigned last)
|
||||
unsigned pci_find_next_capability(struct device * dev, unsigned cap, unsigned last)
|
||||
{
|
||||
unsigned pos;
|
||||
unsigned status;
|
||||
|
|
@ -127,7 +130,7 @@ unsigned pci_find_next_capability(device_t dev, unsigned cap, unsigned last)
|
|||
int this_cap;
|
||||
pos &= ~3;
|
||||
this_cap = pci_read_config8(dev, pos + PCI_CAP_LIST_ID);
|
||||
printk_spew("Capability: 0x%02x @ 0x%02x\n", cap, pos);
|
||||
printk(BIOS_SPEW,"Capability: 0x%02x @ 0x%02x\n", cap, pos);
|
||||
if (this_cap == 0xff) {
|
||||
break;
|
||||
}
|
||||
|
|
@ -142,7 +145,7 @@ unsigned pci_find_next_capability(device_t dev, unsigned cap, unsigned last)
|
|||
return 0;
|
||||
}
|
||||
|
||||
unsigned pci_find_capability(device_t dev, unsigned cap)
|
||||
unsigned pci_find_capability(struct device * dev, unsigned cap)
|
||||
{
|
||||
return pci_find_next_capability(dev, cap, 0);
|
||||
|
||||
|
|
@ -209,7 +212,7 @@ struct resource *pci_get_resource(struct device *dev, unsigned long index)
|
|||
*/
|
||||
if (moving == 0) {
|
||||
if (value != 0) {
|
||||
printk_debug(
|
||||
printk(BIOS_DEBUG,
|
||||
"%s register %02x(%08x), read-only ignoring it\n",
|
||||
dev_path(dev), index, value);
|
||||
}
|
||||
|
|
@ -254,11 +257,11 @@ struct resource *pci_get_resource(struct device *dev, unsigned long index)
|
|||
}
|
||||
#if 0
|
||||
if (resource->flags) {
|
||||
printk_debug("%s %02x ->",
|
||||
printk(BIOS_DEBUG,"%s %02x ->",
|
||||
dev_path(dev), resource->index);
|
||||
printk_debug(" value: 0x%08Lx zeroes: 0x%08Lx ones: 0x%08Lx attr: %08lx\n",
|
||||
printk(BIOS_DEBUG," value: 0x%08Lx zeroes: 0x%08Lx ones: 0x%08Lx attr: %08lx\n",
|
||||
value, zeroes, ones, attr);
|
||||
printk_debug(
|
||||
printk(BIOS_DEBUG,
|
||||
"%s %02x -> size: 0x%08Lx max: 0x%08Lx %s\n ",
|
||||
dev_path(dev),
|
||||
resource->index,
|
||||
|
|
@ -314,7 +317,7 @@ static void pci_get_rom_resource(struct device *dev, unsigned long index)
|
|||
|
||||
if (moving == 0) {
|
||||
if (value != 0) {
|
||||
printk_debug("%s register %02x(%08x), read-only ignoring it\n",
|
||||
printk(BIOS_DEBUG,"%s register %02x(%08x), read-only ignoring it\n",
|
||||
dev_path(dev), index, value);
|
||||
}
|
||||
resource->flags = 0;
|
||||
|
|
@ -458,7 +461,7 @@ static void pci_set_resource(struct device *dev, struct resource *resource)
|
|||
|
||||
/* Make certain the resource has actually been set */
|
||||
if (!(resource->flags & IORESOURCE_ASSIGNED)) {
|
||||
printk_err("ERROR: %s %02x %s size: 0x%010Lx not assigned\n",
|
||||
printk(BIOS_ERR,"ERROR: %s %02x %s size: 0x%010Lx not assigned\n",
|
||||
dev_path(dev), resource->index,
|
||||
resource_type(resource),
|
||||
resource->size);
|
||||
|
|
@ -545,7 +548,7 @@ static void pci_set_resource(struct device *dev, struct resource *resource)
|
|||
else {
|
||||
/* Don't let me think I stored the resource */
|
||||
resource->flags &= ~IORESOURCE_STORED;
|
||||
printk_err("ERROR: invalid resource->index %x\n",
|
||||
printk(BIOS_ERR,"ERROR: invalid resource->index %x\n",
|
||||
resource->index);
|
||||
}
|
||||
report_resource_stored(dev, resource, "");
|
||||
|
|
@ -595,8 +598,10 @@ void pci_dev_enable_resources(struct device *dev)
|
|||
|
||||
/* Set the subsystem vendor and device id for mainboard devices */
|
||||
ops = ops_pci(dev);
|
||||
#warning "Need to do this again: Set the subsystem vendor and device id for mainboard devices"
|
||||
/*
|
||||
if (dev->on_mainboard && ops && ops->set_subsystem) {
|
||||
printk_debug("%s subsystem <- %02x/%02x\n",
|
||||
printk(BIOS_DEBUG,"%s subsystem <- %02x/%02x\n",
|
||||
dev_path(dev),
|
||||
MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID,
|
||||
MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID);
|
||||
|
|
@ -604,10 +609,11 @@ void pci_dev_enable_resources(struct device *dev)
|
|||
MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID,
|
||||
MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID);
|
||||
}
|
||||
*/
|
||||
command = pci_read_config16(dev, PCI_COMMAND);
|
||||
command |= dev->command;
|
||||
command |= (PCI_COMMAND_PARITY + PCI_COMMAND_SERR); /* error check */
|
||||
printk_debug("%s cmd <- %02x\n", dev_path(dev), command);
|
||||
printk(BIOS_DEBUG,"%s cmd <- %02x\n", dev_path(dev), command);
|
||||
pci_write_config16(dev, PCI_COMMAND, command);
|
||||
}
|
||||
|
||||
|
|
@ -621,7 +627,7 @@ void pci_bus_enable_resources(struct device *dev)
|
|||
ctrl = pci_read_config16(dev, PCI_BRIDGE_CONTROL);
|
||||
ctrl |= dev->link[0].bridge_ctrl;
|
||||
ctrl |= (PCI_BRIDGE_CTL_PARITY + PCI_BRIDGE_CTL_SERR); /* error check */
|
||||
printk_debug("%s bridge ctrl <- %04x\n", dev_path(dev), ctrl);
|
||||
printk(BIOS_DEBUG,"%s bridge ctrl <- %04x\n", dev_path(dev), ctrl);
|
||||
pci_write_config16(dev, PCI_BRIDGE_CONTROL, ctrl);
|
||||
|
||||
pci_dev_enable_resources(dev);
|
||||
|
|
@ -641,7 +647,7 @@ void pci_bus_reset(struct bus *bus)
|
|||
delay(1);
|
||||
}
|
||||
|
||||
void pci_dev_set_subsystem(device_t dev, unsigned vendor, unsigned device)
|
||||
void pci_dev_set_subsystem(struct device * dev, unsigned vendor, unsigned device)
|
||||
{
|
||||
pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
|
||||
((device & 0xffff) << 16) | (vendor & 0xffff));
|
||||
|
|
@ -649,6 +655,8 @@ void pci_dev_set_subsystem(device_t dev, unsigned vendor, unsigned device)
|
|||
|
||||
void pci_dev_init(struct device *dev)
|
||||
{
|
||||
#define CONFIG_PCI_ROM_RUN 0
|
||||
#warning "Need to set up CONFIG_PCI_ROM_RUN"
|
||||
#if CONFIG_PCI_ROM_RUN == 1
|
||||
struct rom_header *rom, *ram;
|
||||
|
||||
|
|
@ -669,12 +677,12 @@ static struct pci_operations pci_dev_ops_pci = {
|
|||
};
|
||||
|
||||
struct device_operations default_pci_ops_dev = {
|
||||
.read_resources = pci_dev_read_resources,
|
||||
.set_resources = pci_dev_set_resources,
|
||||
.enable_resources = pci_dev_enable_resources,
|
||||
.init = pci_dev_init,
|
||||
.scan_bus = 0,
|
||||
.enable = 0,
|
||||
.phase4_read_resources = pci_dev_read_resources,
|
||||
.phase4_set_resources = pci_dev_set_resources,
|
||||
.phase5_enable_resources = pci_dev_enable_resources,
|
||||
.phase6_init = pci_dev_init,
|
||||
.phase3_scan = 0,
|
||||
.phase4_enable_disable = 0,
|
||||
.ops_pci = &pci_dev_ops_pci,
|
||||
};
|
||||
|
||||
|
|
@ -684,12 +692,12 @@ static struct pci_operations pci_bus_ops_pci = {
|
|||
};
|
||||
|
||||
struct device_operations default_pci_ops_bus = {
|
||||
.read_resources = pci_bus_read_resources,
|
||||
.set_resources = pci_dev_set_resources,
|
||||
.enable_resources = pci_bus_enable_resources,
|
||||
.init = 0,
|
||||
.scan_bus = pci_scan_bridge,
|
||||
.enable = 0,
|
||||
.phase4_read_resources = pci_bus_read_resources,
|
||||
.phase4_set_resources = pci_dev_set_resources,
|
||||
.phase5_enable_resources = pci_bus_enable_resources,
|
||||
.phase6_init = 0,
|
||||
.phase3_scan = pci_scan_bridge,
|
||||
.phase4_enable_disable = 0,
|
||||
.reset_bus = pci_bus_reset,
|
||||
.ops_pci = &pci_bus_ops_pci,
|
||||
};
|
||||
|
|
@ -711,14 +719,14 @@ struct device_operations default_pci_ops_bus = {
|
|||
*
|
||||
* @return appropriate bridge operations
|
||||
*/
|
||||
static struct device_operations *get_pci_bridge_ops(device_t dev)
|
||||
static struct device_operations *get_pci_bridge_ops(struct device * dev)
|
||||
{
|
||||
unsigned pos;
|
||||
|
||||
#if CONFIG_PCIX_PLUGIN_SUPPORT == 1
|
||||
pos = pci_find_capability(dev, PCI_CAP_ID_PCIX);
|
||||
if (pos) {
|
||||
printk_debug("%s subbordinate bus PCI-X\n", dev_path(dev));
|
||||
printk(BIOS_DEBUG,"%s subbordinate bus PCI-X\n", dev_path(dev));
|
||||
return &default_pcix_ops_bus;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -732,7 +740,7 @@ static struct device_operations *get_pci_bridge_ops(device_t dev)
|
|||
flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
|
||||
if ((flags >> 13) == 1) {
|
||||
/* Host or Secondary Interface */
|
||||
printk_debug("%s subbordinate bus Hypertransport\n",
|
||||
printk(BIOS_DEBUG,"%s subbordinate bus Hypertransport\n",
|
||||
dev_path(dev));
|
||||
return &default_ht_ops_bus;
|
||||
}
|
||||
|
|
@ -747,11 +755,11 @@ static struct device_operations *get_pci_bridge_ops(device_t dev)
|
|||
case PCI_EXP_TYPE_ROOT_PORT:
|
||||
case PCI_EXP_TYPE_UPSTREAM:
|
||||
case PCI_EXP_TYPE_DOWNSTREAM:
|
||||
printk_debug("%s subbordinate bus PCI Express\n",
|
||||
printk(BIOS_DEBUG,"%s subbordinate bus PCI Express\n",
|
||||
dev_path(dev));
|
||||
return &default_pciexp_ops_bus;
|
||||
case PCI_EXP_TYPE_PCI_BRIDGE:
|
||||
printk_debug("%s subbordinate PCI\n",
|
||||
printk(BIOS_DEBUG,"%s subbordinate PCI\n",
|
||||
dev_path(dev));
|
||||
return &default_pci_ops_bus;
|
||||
default:
|
||||
|
|
@ -785,10 +793,10 @@ static void set_pci_ops(struct device *dev)
|
|||
(driver->device == dev->device))
|
||||
{
|
||||
dev->ops = driver->ops;
|
||||
printk_spew("%s [%04x/%04x] %sops\n",
|
||||
printk(BIOS_SPEW,"%s [%04x/%04x] %sops\n",
|
||||
dev_path(dev),
|
||||
driver->vendor, driver->device,
|
||||
(driver->ops->scan_bus?"bus ":""));
|
||||
(driver->ops->phase3_scan?"bus ":""));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -813,7 +821,7 @@ static void set_pci_ops(struct device *dev)
|
|||
default:
|
||||
bad:
|
||||
if (dev->enabled) {
|
||||
printk_err("%s [%04x/%04x/%06x] has unknown header "
|
||||
printk(BIOS_ERR,"%s [%04x/%04x/%06x] has unknown header "
|
||||
"type %02x, ignoring.\n",
|
||||
dev_path(dev),
|
||||
dev->vendor, dev->device,
|
||||
|
|
@ -844,7 +852,7 @@ 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_err("child %s not a pci device\n",
|
||||
printk(BIOS_ERR,"child %s not a pci device\n",
|
||||
dev_path(*list));
|
||||
continue;
|
||||
}
|
||||
|
|
@ -862,7 +870,7 @@ static struct device *pci_scan_get_dev(struct device **list, unsigned int devfn)
|
|||
* order on the bus.
|
||||
*/
|
||||
if (dev) {
|
||||
device_t child;
|
||||
struct device * child;
|
||||
/* Find the last child of our parent */
|
||||
for(child = dev->bus->children; child && child->sibling; ) {
|
||||
child = child->sibling;
|
||||
|
|
@ -889,7 +897,7 @@ static struct device *pci_scan_get_dev(struct device **list, unsigned int devfn)
|
|||
* @return The device structure for hte device (if found)
|
||||
* or the NULL if no device is found.
|
||||
*/
|
||||
device_t pci_probe_dev(device_t dev, struct bus *bus, unsigned devfn)
|
||||
struct device * pci_probe_dev(struct device * dev, struct bus *bus, unsigned devfn)
|
||||
{
|
||||
uint32_t id, class;
|
||||
uint8_t hdr_type;
|
||||
|
|
@ -907,7 +915,7 @@ device_t pci_probe_dev(device_t dev, struct bus *bus, unsigned devfn)
|
|||
if ( (id == 0xffffffff) || (id == 0x00000000) ||
|
||||
(id == 0x0000ffff) || (id == 0xffff0000))
|
||||
{
|
||||
printk_spew("PCI: devfn 0x%x, bad id 0x%x\n", devfn, id);
|
||||
printk(BIOS_SPEW,"PCI: devfn 0x%x, bad id 0x%x\n", devfn, id);
|
||||
return NULL;
|
||||
}
|
||||
dev = alloc_dev(bus, &dummy.path);
|
||||
|
|
@ -943,7 +951,7 @@ device_t pci_probe_dev(device_t dev, struct bus *bus, unsigned devfn)
|
|||
(id == 0x0000ffff) || (id == 0xffff0000))
|
||||
{
|
||||
if (dev->enabled) {
|
||||
printk_info("Disabling static device: %s\n",
|
||||
printk(BIOS_INFO,"Disabling static device: %s\n",
|
||||
dev_path(dev));
|
||||
dev->enabled = 0;
|
||||
}
|
||||
|
|
@ -976,15 +984,15 @@ device_t pci_probe_dev(device_t dev, struct bus *bus, unsigned devfn)
|
|||
set_pci_ops(dev);
|
||||
|
||||
/* Now run the magic enable/disable sequence for the device */
|
||||
if (dev->ops && dev->ops->enable) {
|
||||
dev->ops->enable(dev);
|
||||
if (dev->ops && dev->ops->phase4_enable_disable) {
|
||||
dev->ops->phase4_enable_disable(dev);
|
||||
}
|
||||
|
||||
|
||||
/* Display the device and error if we don't have some pci operations
|
||||
* for it.
|
||||
*/
|
||||
printk_debug("%s [%04x/%04x] %s%s\n",
|
||||
printk(BIOS_DEBUG,"%s [%04x/%04x] %s%s\n",
|
||||
dev_path(dev),
|
||||
dev->vendor, dev->device,
|
||||
dev->enabled?"enabled": "disabled",
|
||||
|
|
@ -1015,13 +1023,13 @@ unsigned int pci_scan_bus(struct bus *bus,
|
|||
unsigned int max)
|
||||
{
|
||||
unsigned int devfn;
|
||||
device_t old_devices;
|
||||
device_t child;
|
||||
struct device * old_devices;
|
||||
struct device * child;
|
||||
|
||||
#if PCI_BUS_SEGN_BITS
|
||||
printk_debug("PCI: pci_scan_bus for bus %04x:%02x\n", bus->secondary >> 8, bus->secondary & 0xff);
|
||||
printk(BIOS_DEBUG,"PCI: pci_scan_bus for bus %04x:%02x\n", bus->secondary >> 8, bus->secondary & 0xff);
|
||||
#else
|
||||
printk_debug("PCI: pci_scan_bus for bus %02x\n", bus->secondary);
|
||||
printk(BIOS_DEBUG,"PCI: pci_scan_bus for bus %02x\n", bus->secondary);
|
||||
#endif
|
||||
|
||||
old_devices = bus->children;
|
||||
|
|
@ -1032,7 +1040,7 @@ unsigned int pci_scan_bus(struct bus *bus,
|
|||
* non-existence and single funcion devices
|
||||
*/
|
||||
for (devfn = min_devfn; devfn <= max_devfn; devfn++) {
|
||||
device_t dev;
|
||||
struct device * dev;
|
||||
|
||||
/* First thing setup the device structure */
|
||||
dev = pci_scan_get_dev(&old_devices, devfn);
|
||||
|
|
@ -1059,9 +1067,9 @@ unsigned int pci_scan_bus(struct bus *bus,
|
|||
* There's probably a problem in the Config.lb.
|
||||
*/
|
||||
if(old_devices) {
|
||||
device_t left;
|
||||
struct device * left;
|
||||
for(left = old_devices; left; left = left->sibling) {
|
||||
printk_err("%s\n", dev_path(left));
|
||||
printk(BIOS_ERR,"%s\n", dev_path(left));
|
||||
}
|
||||
die("PCI: Left over static devices. Check your Config.lb\n");
|
||||
}
|
||||
|
|
@ -1080,7 +1088,7 @@ unsigned int pci_scan_bus(struct bus *bus,
|
|||
*
|
||||
* Return how far we've got finding sub-buses.
|
||||
*/
|
||||
printk_debug("PCI: pci_scan_bus returning with max=%03x\n", max);
|
||||
printk(BIOS_DEBUG,"PCI: pci_scan_bus returning with max=%03x\n", max);
|
||||
post_code(0x55);
|
||||
return max;
|
||||
}
|
||||
|
|
@ -1107,7 +1115,7 @@ unsigned int do_pci_scan_bridge(struct device *dev, unsigned int max,
|
|||
uint32_t buses;
|
||||
uint16_t cr;
|
||||
|
||||
printk_spew("%s for %s\n", __func__, dev_path(dev));
|
||||
printk(BIOS_SPEW,"%s for %s\n", __func__, dev_path(dev));
|
||||
|
||||
bus = &dev->link[0];
|
||||
bus->dev = dev;
|
||||
|
|
@ -1155,7 +1163,7 @@ unsigned int do_pci_scan_bridge(struct device *dev, unsigned int max,
|
|||
pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
|
||||
pci_write_config16(dev, PCI_COMMAND, cr);
|
||||
|
||||
printk_spew("%s returns max %d\n", __func__, max);
|
||||
printk(BIOS_SPEW,"%s returns max %d\n", __func__, max);
|
||||
return max;
|
||||
}
|
||||
|
||||
|
|
@ -1185,10 +1193,10 @@ void pci_level_irq(unsigned char intNum)
|
|||
{
|
||||
unsigned short intBits = inb(0x4d0) | (((unsigned) inb(0x4d1)) << 8);
|
||||
|
||||
printk_spew("%s: current ints are 0x%x\n", __func__, intBits);
|
||||
printk(BIOS_SPEW,"%s: current ints are 0x%x\n", __func__, intBits);
|
||||
intBits |= (1 << intNum);
|
||||
|
||||
printk_spew("%s: try to set ints 0x%x\n", __func__, intBits);
|
||||
printk(BIOS_SPEW,"%s: try to set ints 0x%x\n", __func__, intBits);
|
||||
|
||||
// Write new values
|
||||
outb((unsigned char) intBits, 0x4d0);
|
||||
|
|
@ -1197,11 +1205,11 @@ void pci_level_irq(unsigned char intNum)
|
|||
/* this seems like an error but is not ... */
|
||||
#if 1
|
||||
if (inb(0x4d0) != (intBits & 0xff)) {
|
||||
printk_err("%s: lower order bits are wrong: want 0x%x, got 0x%x\n",
|
||||
printk(BIOS_ERR,"%s: lower order bits are wrong: want 0x%x, got 0x%x\n",
|
||||
__func__, intBits &0xff, inb(0x4d0));
|
||||
}
|
||||
if (inb(0x4d1) != ((intBits >> 8) & 0xff)) {
|
||||
printk_err("%s: lower order bits are wrong: want 0x%x, got 0x%x\n",
|
||||
printk(BIOS_ERR,"%s: lower order bits are wrong: want 0x%x, got 0x%x\n",
|
||||
__func__, (intBits>>8) &0xff, inb(0x4d1));
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1225,7 +1233,7 @@ void pci_assign_irqs(unsigned bus, unsigned slot,
|
|||
const unsigned char pIntAtoD[4])
|
||||
{
|
||||
unsigned functNum;
|
||||
device_t pdev;
|
||||
struct device * pdev;
|
||||
unsigned char line;
|
||||
unsigned char irq;
|
||||
unsigned char readback;
|
||||
|
|
@ -1241,14 +1249,14 @@ void pci_assign_irqs(unsigned bus, unsigned slot,
|
|||
if ((line >= 1) && (line <= 4)) {
|
||||
irq = pIntAtoD[line - 1];
|
||||
|
||||
printk_debug("Assigning IRQ %d to %d:%x.%d\n", \
|
||||
printk(BIOS_DEBUG,"Assigning IRQ %d to %d:%x.%d\n", \
|
||||
irq, bus, slot, functNum);
|
||||
|
||||
pci_write_config8(pdev, PCI_INTERRUPT_LINE,\
|
||||
pIntAtoD[line - 1]);
|
||||
|
||||
readback = pci_read_config8(pdev, PCI_INTERRUPT_LINE);
|
||||
printk_debug(" Readback = %d\n", readback);
|
||||
printk(BIOS_DEBUG," Readback = %d\n", readback);
|
||||
|
||||
// Change to level triggered
|
||||
pci_level_irq(pIntAtoD[line - 1]);
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
#include <device/pci_ids.h>
|
||||
#include <device/pci_ops.h>
|
||||
|
||||
static struct bus *get_pbus(device_t dev)
|
||||
static struct bus *get_pbus(struct device * dev)
|
||||
{
|
||||
struct bus *pbus = dev->bus;
|
||||
while(pbus && pbus->dev && !ops_pci_bus(pbus)) {
|
||||
|
|
@ -34,37 +34,37 @@ static struct bus *get_pbus(device_t dev)
|
|||
return pbus;
|
||||
}
|
||||
|
||||
uint8_t pci_read_config8(device_t dev, unsigned where)
|
||||
uint8_t pci_read_config8(struct device * dev, unsigned where)
|
||||
{
|
||||
struct bus *pbus = get_pbus(dev);
|
||||
return ops_pci_bus(pbus)->read8(pbus, dev->bus->secondary, dev->path.u.pci.devfn, where);
|
||||
}
|
||||
|
||||
uint16_t pci_read_config16(device_t dev, unsigned where)
|
||||
uint16_t pci_read_config16(struct device * dev, unsigned where)
|
||||
{
|
||||
struct bus *pbus = get_pbus(dev);
|
||||
return ops_pci_bus(pbus)->read16(pbus, dev->bus->secondary, dev->path.u.pci.devfn, where);
|
||||
}
|
||||
|
||||
uint32_t pci_read_config32(device_t dev, unsigned where)
|
||||
uint32_t pci_read_config32(struct device * dev, unsigned where)
|
||||
{
|
||||
struct bus *pbus = get_pbus(dev);
|
||||
return ops_pci_bus(pbus)->read32(pbus, dev->bus->secondary, dev->path.u.pci.devfn, where);
|
||||
}
|
||||
|
||||
void pci_write_config8(device_t dev, unsigned where, uint8_t val)
|
||||
void pci_write_config8(struct device * dev, unsigned where, uint8_t val)
|
||||
{
|
||||
struct bus *pbus = get_pbus(dev);
|
||||
ops_pci_bus(pbus)->write8(pbus, dev->bus->secondary, dev->path.u.pci.devfn, where, val);
|
||||
}
|
||||
|
||||
void pci_write_config16(device_t dev, unsigned where, uint16_t val)
|
||||
void pci_write_config16(struct device * dev, unsigned where, uint16_t val)
|
||||
{
|
||||
struct bus *pbus = get_pbus(dev);
|
||||
ops_pci_bus(pbus)->write16(pbus, dev->bus->secondary, dev->path.u.pci.devfn, where, val);
|
||||
}
|
||||
|
||||
void pci_write_config32(device_t dev, unsigned where, uint32_t val)
|
||||
void pci_write_config32(struct device * dev, unsigned where, uint32_t val)
|
||||
{
|
||||
struct bus *pbus = get_pbus(dev);
|
||||
ops_pci_bus(pbus)->write32(pbus, dev->bus->secondary, dev->path.u.pci.devfn, where, val);
|
||||
|
|
|
|||
|
|
@ -111,8 +111,8 @@ unsigned int scan_static_bus(struct device * busdevice, unsigned int max)
|
|||
child->chip_ops->enable_dev(child);
|
||||
}
|
||||
/* sigh. Have to enable to scan ... */
|
||||
if (child->ops && child->ops->phase5) {
|
||||
child->ops->phase5(child);
|
||||
if (child->ops && child->ops->phase5_enable_resources) {
|
||||
child->ops->phase5_enable_resources(child);
|
||||
}
|
||||
if (child->path.type == DEVICE_PATH_I2C) {
|
||||
printk(BIOS_DEBUG, "smbus: %s[%d]->",
|
||||
|
|
@ -125,10 +125,10 @@ unsigned int scan_static_bus(struct device * busdevice, unsigned int max)
|
|||
}
|
||||
for(link = 0; link < busdevice->links; link++) {
|
||||
for(child = busdevice->link[link].children; child; child = child->sibling) {
|
||||
if (!child->ops || !child->ops->phase3)
|
||||
if (!child->ops || !child->ops->phase3_scan)
|
||||
continue;
|
||||
printk(BIOS_SPEW, "%s scanning...\n", dev_path(child));
|
||||
max = dev_phase3(child, max);
|
||||
max = dev_phase3_scan(child, max);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -199,9 +199,9 @@ void root_dev_reset(struct bus *bus)
|
|||
struct device_operations default_dev_ops_root = {
|
||||
.phase4_read_resources = root_dev_read_resources,
|
||||
.phase4_set_resources = root_dev_set_resources,
|
||||
.phase5 = root_dev_enable_resources,
|
||||
.phase6 = root_dev_init,
|
||||
.phase3 = root_dev_scan_bus,
|
||||
.phase5_enable_resources = root_dev_enable_resources,
|
||||
.phase6_init = root_dev_init,
|
||||
.phase3_scan = root_dev_scan_bus,
|
||||
.reset_bus = root_dev_reset,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,6 @@ struct bus;
|
|||
* The numbering is nice, the naming is nice, what to do?
|
||||
*/
|
||||
struct device_operations {
|
||||
// void (*enable)(struct device * dev);
|
||||
/* for now, we leave these, since they seem generic */
|
||||
void (*set_link)(struct device * dev, unsigned int link);
|
||||
void (*reset_bus)(struct bus *bus);
|
||||
|
|
@ -55,18 +54,21 @@ struct device_operations {
|
|||
void (*phase2)(struct device * dev);
|
||||
|
||||
/* phase 3 is for scanning the bus, if needed. */
|
||||
unsigned int (*phase3)(struct device * bus, unsigned int max);
|
||||
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)(struct device * dev);
|
||||
void (*phase5_enable_resources)(struct device * dev);
|
||||
|
||||
/* phase 6: any post-setup device initialization that might be needed */
|
||||
void (*phase6)(struct device * dev);
|
||||
void (*phase6_init)(struct device * dev);
|
||||
|
||||
const struct pci_operations *ops_pci;
|
||||
const struct smbus_bus_operations *ops_smbus_bus;
|
||||
|
|
@ -182,6 +184,7 @@ 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);
|
||||
|
|
|
|||
|
|
@ -22,4 +22,8 @@
|
|||
|
||||
unsigned long log2(unsigned long x);
|
||||
|
||||
void udelay(unsigned usecs);
|
||||
void mdelay(unsigned msecs);
|
||||
void delay(unsigned secs);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
34
lib/delay.c
Normal file
34
lib/delay.c
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* This file is part of the LinuxBIOS project.
|
||||
*
|
||||
* Copyright (C) FIXME GET HISTORY
|
||||
*
|
||||
* 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; version 2 of the License.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include <lib.h>
|
||||
void mdelay(unsigned msecs)
|
||||
{
|
||||
unsigned i;
|
||||
for(i = 0; i < msecs; i++) {
|
||||
udelay(1000);
|
||||
}
|
||||
}
|
||||
void delay(unsigned secs)
|
||||
{
|
||||
unsigned i;
|
||||
for(i = 0; i < secs; i++) {
|
||||
mdelay(1000);
|
||||
}
|
||||
}
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
device_type = "cpu";
|
||||
name = "emulation,qemu-i386";
|
||||
pcidomain = "0";
|
||||
|
||||
ops="i440bxemulation,pcidomainops";
|
||||
/* the I/O stuff */
|
||||
northbridge,intel,440bx{
|
||||
config="northbridge,intel,i440bxemulation";
|
||||
|
|
@ -24,6 +24,8 @@
|
|||
|
||||
%%
|
||||
|
||||
extern struct device_operations i440bxemulation_pcidomainops;
|
||||
|
||||
struct mainboard_emulation_qemu_i386_config root = {
|
||||
.nothing = 1,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include <console/console.h>
|
||||
#include <stdint.h>
|
||||
#include <device/device.h>
|
||||
#include <device/pci.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "config.h"
|
||||
|
|
@ -44,3 +45,64 @@ struct chip_operations northbridge_intel_i440bxemulation_ops = {
|
|||
.name="Intel 440BX Northbridge Emulation",
|
||||
.enable_dev = i440bxemulation_enable_dev,
|
||||
};
|
||||
|
||||
/* here are the ops for 440bx as a pci domain */
|
||||
|
||||
static void pci_domain_read_resources(struct device * dev)
|
||||
{
|
||||
struct resource *resource;
|
||||
|
||||
/* Initialize the system wide io space constraints */
|
||||
resource = new_resource(dev, IOINDEX_SUBTRACTIVE(0,0));
|
||||
resource->limit = 0xffffUL;
|
||||
resource->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
|
||||
|
||||
/* Initialize the system wide memory resources constraints */
|
||||
resource = new_resource(dev, IOINDEX_SUBTRACTIVE(1,0));
|
||||
resource->limit = 0xffffffffULL;
|
||||
resource->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
|
||||
}
|
||||
|
||||
static void ram_resource(struct device * dev, unsigned long index,
|
||||
unsigned long basek, unsigned long sizek)
|
||||
{
|
||||
struct resource *resource;
|
||||
|
||||
if (!sizek) {
|
||||
return;
|
||||
}
|
||||
resource = new_resource(dev, index);
|
||||
resource->base = ((resource_t)basek) << 10;
|
||||
resource->size = ((resource_t)sizek) << 10;
|
||||
resource->flags = IORESOURCE_MEM | IORESOURCE_CACHEABLE | \
|
||||
IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED;
|
||||
}
|
||||
|
||||
static void pci_domain_set_resources(struct device * dev)
|
||||
{
|
||||
struct device * mc_dev;
|
||||
uint32_t tolmk; /* top of low mem, Kbytes */
|
||||
int idx;
|
||||
struct northbridge_intel_i440bx_config *chip_info = dev->chip_info;
|
||||
tolmk = chip_info->ramsize * 1024;
|
||||
mc_dev = dev->link[0].children;
|
||||
if (mc_dev) {
|
||||
idx = 10;
|
||||
ram_resource(dev, idx++, 0, tolmk);
|
||||
}
|
||||
phase4_assign_resources(&dev->link[0]);
|
||||
}
|
||||
|
||||
static unsigned int pci_domain_scan_bus(struct device * dev, unsigned int max)
|
||||
{
|
||||
max = pci_scan_bus(&dev->link[0], PCI_DEVFN(0, 0), 0xff, max);
|
||||
return max;
|
||||
}
|
||||
|
||||
struct device_operations i440bxemulation_pcidomainops = {
|
||||
.phase4_read_resources = pci_domain_read_resources,
|
||||
.phase4_set_resources = pci_domain_set_resources,
|
||||
.phase5_enable_resources = enable_childrens_resources,
|
||||
.phase6_init = 0,
|
||||
.phase3_scan = pci_domain_scan_bus,
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue