From 1ff0923db65dd56c046dcbd343380d3eeca69e8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sat, 19 Mar 2005 02:35:40 +0000 Subject: [PATCH] Removed the old (and nowadays unused) addons directory and related headers. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@11915 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/kernel/bus.h | 39 - headers/private/kernel/isa.h | 58 - src/kernel/core/Jamfile | 1 - src/kernel/core/addons/Jamfile | 3 - src/kernel/core/addons/bus_managers/Jamfile | 12 - .../core/addons/bus_managers/bus_init.c | 51 - .../core/addons/bus_managers/isa/Jamfile | 17 - src/kernel/core/addons/bus_managers/isa/isa.c | 125 -- .../core/addons/bus_managers/pci/Jamfile | 18 - src/kernel/core/addons/bus_managers/pci/pci.c | 1431 ----------------- .../core/addons/bus_managers/pci/pci_bus.c | 347 ---- src/kernel/core/main.c | 1 - 12 files changed, 2103 deletions(-) delete mode 100644 headers/private/kernel/bus.h delete mode 100644 headers/private/kernel/isa.h delete mode 100644 src/kernel/core/addons/Jamfile delete mode 100644 src/kernel/core/addons/bus_managers/Jamfile delete mode 100644 src/kernel/core/addons/bus_managers/bus_init.c delete mode 100644 src/kernel/core/addons/bus_managers/isa/Jamfile delete mode 100644 src/kernel/core/addons/bus_managers/isa/isa.c delete mode 100644 src/kernel/core/addons/bus_managers/pci/Jamfile delete mode 100644 src/kernel/core/addons/bus_managers/pci/pci.c delete mode 100644 src/kernel/core/addons/bus_managers/pci/pci_bus.c diff --git a/headers/private/kernel/bus.h b/headers/private/kernel/bus.h deleted file mode 100644 index d1e6feb72d..0000000000 --- a/headers/private/kernel/bus.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -** Copyright 2001, Travis Geiselbrecht. All rights reserved. -** Distributed under the terms of the NewOS License. -*/ -#ifndef KERNEL_BUS_H -#define KERNEL_BUS_H - - -#include - - -struct kernel_args; - -int bus_init(struct kernel_args *ka); -int bus_man_init(struct kernel_args *ka); - -int bus_register_bus(const char *path); - -typedef struct id_list { - uint32 num_ids; - uint32 id[0]; -} id_list; - -#define MAX_DEV_IO_RANGES 8 - -typedef struct device { - uint32 vendor_id; - uint32 device_id; - - uint32 irq; - addr_t base[MAX_DEV_IO_RANGES]; - addr_t size[MAX_DEV_IO_RANGES]; - - char dev_path[256]; -} device; - -int bus_find_device(int n, id_list *vendor_ids, id_list *device_ids, device *dev); - -#endif /* KERNEL_BUS_H */ diff --git a/headers/private/kernel/isa.h b/headers/private/kernel/isa.h deleted file mode 100644 index e09ef97406..0000000000 --- a/headers/private/kernel/isa.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -** Copyright 2002, Thomas Kurschel. All rights reserved. -** Distributed under the terms of the NewOS License. -*/ - -// this is not to be taken seriously - it's just a simple module - -#ifndef __ISA_H__ -#define __ISA_H__ - -#include -#include - -#define ISA_MODULE_NAME "bus_managers/isa/v1" - -typedef struct { - ulong address; /* memory address (little endian!) 4 bytes */ - ushort transfer_count; /* # transfers minus one (little endian!) 2 bytes*/ - uchar reserved; /* filler, 1byte*/ - uchar flag; /* end of link flag, 1byte */ -} isa_dma_entry; - -typedef struct { - bus_manager_info binfo; - uint8 (*read_io_8) (int mapped_io_addr); - void (*write_io_8) (int mapped_io_addr, uint8 value); - uint16 (*read_io_16) (int mapped_io_addr); - void (*write_io_16) (int mapped_io_addr, uint16 value); - uint32 (*read_io_32) (int mapped_io_addr); - void (*write_io_32) (int mapped_io_addr, uint32 value); - void *(*ram_address) (const void *physical_address_in_system_memory); - - long (*make_isa_dma_table) ( - const void *buffer, /* buffer to make a table for */ - long buffer_size, /* buffer size */ - ulong num_bits, /* dma transfer size that will be used */ - isa_dma_entry *table, /* -> caller-supplied scatter/gather table */ - long num_entries /* max # entries in table */ - ); - long (*start_isa_dma) ( - long channel, /* dma channel to use */ - void *buf, /* buffer to transfer */ - long transfer_count, /* # transfers */ - uchar mode, /* mode flags */ - uchar e_mode /* extended mode flags */ - ); - long (*start_scattered_isa_dma) ( - long channel, /* channel # to use */ - const isa_dma_entry *table, /* physical address of scatter/gather table */ - uchar mode, /* mode flags */ - uchar emode /* extended mode flags */ - ); - long (*lock_isa_dma_channel) (long channel); - long (*unlock_isa_dma_channel) (long channel); - -} isa_bus_manager; - -#endif diff --git a/src/kernel/core/Jamfile b/src/kernel/core/Jamfile index e04584b53a..8b96a1fbaf 100644 --- a/src/kernel/core/Jamfile +++ b/src/kernel/core/Jamfile @@ -57,7 +57,6 @@ KernelLd linkhack.so : -shared -Bdynamic ; -SubInclude OBOS_TOP src kernel core addons ; SubInclude OBOS_TOP src kernel core arch ; SubInclude OBOS_TOP src kernel core cache ; SubInclude OBOS_TOP src kernel core device_manager ; diff --git a/src/kernel/core/addons/Jamfile b/src/kernel/core/addons/Jamfile deleted file mode 100644 index af7dbf497b..0000000000 --- a/src/kernel/core/addons/Jamfile +++ /dev/null @@ -1,3 +0,0 @@ -SubDir OBOS_TOP src kernel core addons ; - -SubInclude OBOS_TOP src kernel core addons bus_managers ; diff --git a/src/kernel/core/addons/bus_managers/Jamfile b/src/kernel/core/addons/bus_managers/Jamfile deleted file mode 100644 index 6cdadc8cb5..0000000000 --- a/src/kernel/core/addons/bus_managers/Jamfile +++ /dev/null @@ -1,12 +0,0 @@ -SubDir OBOS_TOP src kernel core addons bus_managers ; - -KernelStaticLibrary libbus : - <$(SOURCE_GRIST)>bus_init.c - : - -fno-pic -D_KERNEL_MODE - ; - -if $(OBOS_ARCH) = x86 { - SubInclude OBOS_TOP src kernel core addons bus_managers isa ; -} -# SubInclude OBOS_TOP src kernel core addons bus_managers pci ; diff --git a/src/kernel/core/addons/bus_managers/bus_init.c b/src/kernel/core/addons/bus_managers/bus_init.c deleted file mode 100644 index 4e41f9c381..0000000000 --- a/src/kernel/core/addons/bus_managers/bus_init.c +++ /dev/null @@ -1,51 +0,0 @@ -/* -** Copyright 2001, Travis Geiselbrecht. All rights reserved. -** Distributed under the terms of the NewOS License. -*/ -#include -#include -#include -#include -#include -#include - - -int bus_init(kernel_args *ka) -{ - struct config_manager_for_driver_module_info *cfm; - -#if 0 - bus_man_init(ka); -#endif - - if (get_module(B_CONFIG_MANAGER_FOR_DRIVER_MODULE_NAME, - (module_info**)&cfm) == 0) { - dprintf("bus_init: loaded the config_manager\n"); - } - -#if 0 - { - id_list *vendor_ids; - id_list *device_ids; - device dev; - int rc; - - vendor_ids = kmalloc(sizeof(id_list) + sizeof(uint32)); - vendor_ids->num_ids = 1; - vendor_ids->id[0] = 0x10ec; - - device_ids = kmalloc(sizeof(id_list) + sizeof(uint32)); - device_ids->num_ids = 1; - device_ids->id[0] = 0x8139; - - rc = bus_find_device(1, vendor_ids, device_ids, &dev); - if(rc >= 0) { - dprintf("found device : v 0x%x, d 0x%x, irq 0x%x\n", dev.vendor_id, dev.device_id, dev.irq); - } - kfree(vendor_ids); - kfree(device_ids); - } -#endif - - return 0; -} diff --git a/src/kernel/core/addons/bus_managers/isa/Jamfile b/src/kernel/core/addons/bus_managers/isa/Jamfile deleted file mode 100644 index f7a3c931b9..0000000000 --- a/src/kernel/core/addons/bus_managers/isa/Jamfile +++ /dev/null @@ -1,17 +0,0 @@ -SubDir OBOS_TOP src kernel core addons bus_managers isa ; - -KernelObjects isa.c : -fno-pic -D_KERNEL_MODE ; - -KernelLd old_isa - : - <$(SOURCE_GRIST)>isa.o - kernel.so - : - $(OBOS_TOP)/src/kernel/ldscripts/$(OBOS_ARCH)/add-on.ld - : - -Bdynamic -shared - : - : - addons/kernel/isa - ; - diff --git a/src/kernel/core/addons/bus_managers/isa/isa.c b/src/kernel/core/addons/bus_managers/isa/isa.c deleted file mode 100644 index bcb3781129..0000000000 --- a/src/kernel/core/addons/bus_managers/isa/isa.c +++ /dev/null @@ -1,125 +0,0 @@ -/* -** Copyright 2002, Thomas Kurschel. All rights reserved. -** Distributed under the terms of the NewOS License. -*/ - -#include -#include -#include -#include -#include -#include - -static status_t isa_rescan(void) -{ - dprintf("isa_rescan()\n"); - return 0; -} - -static uint8 isa_read_io_8(int mapped_io_addr) -{ - return in8(mapped_io_addr); -} - -static void isa_write_io_8(int mapped_io_addr, uint8 value) -{ - out8(value, mapped_io_addr); -} - -static uint16 isa_read_io_16( int mapped_io_addr ) -{ - return in16(mapped_io_addr); -} - -static void isa_write_io_16( int mapped_io_addr, uint16 value ) -{ - out16(value, mapped_io_addr); -} - -static uint32 isa_read_io_32( int mapped_io_addr ) -{ - return in32(mapped_io_addr); -} - -static void isa_write_io_32( int mapped_io_addr, uint32 value ) -{ - out32(value, mapped_io_addr); -} - -static void *ram_address(const void *physical_address_in_system_memory) -{ - dprintf("isa: ram_address\n"); - return NULL; -} - -static long make_isa_dma_table(const void *buffer, long buffer_size, - ulong num_bits, isa_dma_entry *table, - long num_entries) -{ - return ENOSYS; -} - -static long start_isa_dma(long channel, void *buf, long transfer_count, - uchar mode, uchar e_mode) -{ - return ENOSYS; -} - -static long start_scattered_isa_dma(long channel, const isa_dma_entry *table, - uchar mode, uchar emode) -{ - return ENOSYS; -} - -static long lock_isa_dma_channel(long channel) -{ - return ENOSYS; -} - -static long unlock_isa_dma_channel(long channel) -{ - return ENOSYS; -} - -static int32 std_ops(int32 op, ...) -{ - switch(op) { - case B_MODULE_INIT: - dprintf( "ISA: init\n" ); - break; - case B_MODULE_UNINIT: - dprintf( "ISA: uninit\n" ); - break; - default: - return EINVAL; - } - return B_OK; -} - -static isa_module_info isa_module = { - { - { - B_ISA_MODULE_NAME, - B_KEEP_LOADED, - std_ops - }, - &isa_rescan - }, - &isa_read_io_8, - &isa_write_io_8, - &isa_read_io_16, - &isa_write_io_16, - &isa_read_io_32, - &isa_write_io_32, - &ram_address, - &make_isa_dma_table, - &start_isa_dma, - &start_scattered_isa_dma, - &lock_isa_dma_channel, - &unlock_isa_dma_channel -}; - -module_info *modules[] = { - (module_info*) &isa_module, - NULL -}; diff --git a/src/kernel/core/addons/bus_managers/pci/Jamfile b/src/kernel/core/addons/bus_managers/pci/Jamfile deleted file mode 100644 index 2ed9582c69..0000000000 --- a/src/kernel/core/addons/bus_managers/pci/Jamfile +++ /dev/null @@ -1,18 +0,0 @@ -SubDir OBOS_TOP src kernel core addons bus_managers pci ; - -KernelStaticLibrary libbuspci : pci.c pci_bus.c ; - -KernelLd - pci - : - <$(SOURCE_GRIST)>pci.o - <$(SOURCE_GRIST)>pci_bus.o - kernel.so - : - $(OBOS_TOP)/src/kernel/ldscripts/$(OBOS_ARCH)/add-on.ld - : - -Bdynamic -shared - : - : - addons/kernel/pci - ; diff --git a/src/kernel/core/addons/bus_managers/pci/pci.c b/src/kernel/core/addons/bus_managers/pci/pci.c deleted file mode 100644 index d84d427c9d..0000000000 --- a/src/kernel/core/addons/bus_managers/pci/pci.c +++ /dev/null @@ -1,1431 +0,0 @@ -/* -** Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. -** Distributed under the terms of the NewOS License. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#define TRACE_PCI 0 -#if TRACE_PCI -# define TRACE(x) dprintf x -#else -# define TRACE(x) ; -#endif - - -/* - * pci_device - */ -typedef struct pci_device pci_device; - -struct pci_device { - pci_device *next; - int type; - pci_info *info; -}; - - -/* - * pci_bus - */ -typedef struct pci_bus pci_bus; - -struct pci_bus { - pci_bus *next; - pci_info *info; -}; - - -enum { - PCI_DEVICE = 0, - PCI_HOST_BUS, - PCI_BRIDGE, - PCI_CARDBUS -}; - -// forward declarations -static char *decode_class(uint8 base, uint8 sub_class); -static void pci_scan_bus(uint8 bus); -//static void scan_pci(void); -static void pci_bridge(uint8 bus, uint8 dev, uint8 func); -static void fill_basic_pci_structure(pci_info *pciInfo); -static uint32 read_pci_config(uchar, uchar, uchar, uchar, uchar); -static void write_pci_config (uchar, uchar, uchar, uchar, uchar, uint32); - -/** globals **/ - -static pci_device *gPCI_Devices = NULL; -static pci_bus *gPCI_Busses = NULL; - -static spinlock gConfigLock = 0; /* lock for config space access */ -static int gConfigMechanism = 1; /* The pci config mechanism we're using. - * Note: defaults to 1 as this is more common, but - * checked at runtime - */ -static int gMaxBusDevices = 32; /* max devices that any bus can support - * Yes, if we're using gConfigMechanism == 2 then - * this is only 16, instead of the 32 we - * have with gConfigMechanism == 1 - */ -static int gMaxBusDetected = 0; /* maximum bus we've found/configured */ - -static region_id gPCI_Region; /* pci_bios region we map */ -static addr gPCI_BIOS_Address = 0; /* virtual address of memory we map */ - - -/* ToDo: move these to a header file */ -#define PCI_VENDOR_INTEL 0x8086 - -#define PCI_PRODUCT_INTEL_82371AB_ISA 0x7110 /* PIIX4 ISA */ -#define PCI_PRODUCT_INTEL_82371AB_IDE 0x7111 /* PIIX4 IDE */ -#define PCI_PRODUCT_INTEL_82371AB_USB 0x7112 /* PIIX4 USB */ -#define PCI_PRODUCT_INTEL_82371AB_PMC 0x7113 /* PIIX4 Power Management */ - -#define PCI_PRODUCT_INTEL_82443BX 0x7190 -#define PCI_PRODUCT_INTEL_82443BX_AGP 0x7191 -#define PCI_PRODUCT_INTEL_82443BX_NOAGP 0x7192 - -/* Config space locking! - * We need to make sure we only have one access at a time into the config space, - * so we'll use a spinlock and also disbale interrupts so if we're smp we - * won't have problems. - */ - -#define PCI_LOCK_CONFIG(status) \ -{ \ - status = disable_interrupts(); \ - acquire_spinlock(&gConfigLock); \ -} - -#define PCI_UNLOCK_CONFIG(cpu_status) \ -{ \ - release_spinlock(&gConfigLock); \ - restore_interrupts(cpu_status); \ -} - - -/* decode_class - * DEBUG DEBUG DEBUG - * Provide a string that describes the class and sub-class. - * This could/should (?) be expanded to use the api as well. - */ - -static char * -decode_class(uint8 base, uint8 sub_class) -{ - switch (base) { - case PCI_early: - switch (sub_class) { - case PCI_early_not_vga: return "legacy (non VGA)"; - case PCI_early_vga: return "legacy VGA"; - } - case 0x01: - switch (sub_class) { - case PCI_scsi: return "mass storage: scsi"; - case PCI_ide: return "mass storage: ide"; - case PCI_floppy: return "mass storage: floppy"; - case PCI_ipi: return "mass storage: ipi"; - case PCI_raid: return "mass storage: raid"; - case PCI_mass_storage_other: - return "mass storage: other"; - } - case 0x02: - switch (sub_class) { - case PCI_ethernet: return "network: ethernet"; - case PCI_token_ring: return "network: token ring"; - case PCI_fddi: return "network: fddi"; - case PCI_atm: return "network: atm"; - case PCI_network_other: - return "network: other"; - } - case 0x03: - switch (sub_class) { - case PCI_vga: return "display: vga"; - case PCI_xga: return "display: xga"; - case PCI_display_other: - return "display: other"; - } - case 0x04: - switch (sub_class) { - case PCI_video: return "multimedia device: video"; - case PCI_audio: return "multimedia device: audio"; - case PCI_multimedia_other: - return "multimedia device: other"; - } - case 0x05: return "memory"; - case 0x06: - switch (sub_class) { - case PCI_host: return "bridge: host bridge"; - case PCI_isa: return "bridge: isa"; - case PCI_eisa: return "bridge: eisa"; - case PCI_microchannel: return "bridge: microchannel"; - case PCI_pci: return "bridge: PCI"; - case PCI_pcmcia: return "bridge: PC Card"; - case PCI_nubus: return "bridge: nubus"; - case PCI_cardbus: return "bridge: CardBus"; - case PCI_bridge_other: - return "bridge: other"; - } - case 0x07: return "simple comms controller"; - case 0x08: return "base system peripheral"; - case 0x09: return "input device"; - case 0x0a: return "docking station"; - case 0x0b: return "processor"; - case 0x0c: - switch (sub_class) { - case PCI_firewire: return "bus: IEEE1394 FireWire"; - case PCI_access: return "bus: ACCESS.bus"; - case PCI_ssa: return "bus: SSA"; - case PCI_usb: return "bus: USB"; - case PCI_fibre_channel: - return "bus: fibre channel"; - } - case 0x0d: return "wireless"; - case 0x0e: return "intelligent i/o ??"; - case 0x0f: return "satellite"; - case 0x10: return "encryption"; - case 0x11: return "signal processing"; - - default: return "unknown"; - } -} - - -static void -show_pci_details(struct pci_info *p) -{ -#if TRACE_PCI - uint16 ss_vend, ss_dev; -#endif - uint8 irq = 0; - - if (p->header_type == PCI_header_type_generic) - irq = p->u.h0.interrupt_line; - else - irq = p->u.h1.interrupt_line; - - dprintf("0x%04x:0x%04x : ", p->vendor_id, p->device_id); - - if (irq > 0) - dprintf("irq %d : ", irq); - - dprintf("location %d:%d:%d : ", p->bus, p->device, p->function); - dprintf("class %02x:%02x:%02x", p->class_base, p->class_sub, - p->class_api); - dprintf(" => %s\n", decode_class(p->class_base, p->class_sub)); - -#if TRACE_PCI - dprintf("\trevision : %02x\n", p->revision); - dprintf("\tstatus : %04x\n", - read_pci_config(p->bus, p->device, p->function, PCI_status, 2)); - dprintf("\tcommand : %04x\n", - read_pci_config(p->bus, p->device, p->function, PCI_command, 2)); - dprintf("\tbase address: %08x\n", - read_pci_config(p->bus, p->device, p->function, PCI_base_registers, 4)); - - dprintf("\tline_size : %02x\n", p->line_size); - dprintf("\theader_type : %02x\n", p->header_type); - - if (p->header_type == PCI_header_type_generic) { - dprintf("Header Type 0 (Generic)\n"); - dprintf("\tcardbus_cis : %08lx\n", p->u.h0.cardbus_cis); - dprintf("\trom_base_pci : %08lx\n", p->u.h0.rom_base_pci); - dprintf("\tinterrupt_line : %02x\n", p->u.h0.interrupt_line); - dprintf("\tinterrupt_pin : %02x\n", p->u.h0.interrupt_pin); - ss_vend = p->u.h0.subsystem_vendor_id; - ss_dev = p->u.h0.subsystem_id; - } else if (p->header_type == PCI_header_type_PCI_to_PCI_bridge) { - dprintf("Header Type 1 (PCI-PCI bridge)\n"); - dprintf("\trom_base_pci : %08lx\n", p->u.h1.rom_base_pci); - dprintf("\tinterrupt_line : %02x\n", p->u.h1.interrupt_line); - dprintf("\tinterrupt_pin : %02x\n", p->u.h1.interrupt_pin); - dprintf("\t2ndry status : %04x\n", p->u.h1.secondary_status); - dprintf("\tprimary_bus : %d\n", p->u.h1.primary_bus); - dprintf("\tsecondary_bus : %d\n", p->u.h1.secondary_bus); - dprintf("\tsubordinate_bus : %d\n", p->u.h1.subordinate_bus); - - ss_vend = p->u.h1.subsystem_vendor_id; - ss_dev = p->u.h1.subsystem_id; - } - dprintf("\tsubsystem_id : %04x\n", ss_dev); - dprintf("\tsubsystem_vendor_id : %04x\n", ss_vend); -#endif -} - - -/* PCI has 2 Configuration Mechanisms. We need to decide which one the - * PCI Host Bridge is speaking and then speak to it correctly. This is decided - * in set_pci_mechanism() where the gConfigMechanism value is set to the appropriate - * value and the gMaxBusDevices value is set correctly. - * - * Mechanism 1 - * =========== - * Mechanism 1 is the more common one found on modern computers, so presently - * that's the one that has been tested and added. - * - * This has 2 ranges, one for addressing and for data. Basically we write in the details of - * the configuration information we want (bus, device and function) and then either - * read or write from the data port. - * - * Apparently most modern hardware no longer has Configuration Type #2. - * - * - * Mechanism 2 - * =========== - * ToDO: add code for mechanism 2! - * - */ - -#define CONFIG_REQ_PORT 0xCF8 -#define CONFIG_DATA_PORT 0xCFC - -#define CONFIG_ADDR_1(bus, device, func, reg) \ - (0x80000000 | (bus << 16) | (device << 11) | (func << 8) | (reg & ~3)) - -#define CONFIG_ADDR_2(dev, reg) \ - (uint16)(0xC00 | (dev << 8) | reg) - - -static uint32 -read_pci_config(uchar bus, uchar device, uchar function, uchar reg, uchar size) -{ - int cpu_status; - uint32 val = 0; - - PCI_LOCK_CONFIG(cpu_status); - - if (gConfigMechanism == 1) { - // write request details - out32(CONFIG_ADDR_1(bus, device, function, reg), CONFIG_REQ_PORT); - // Now read data back from the data port: - // offset for 1 byte can be 1, 2 or 3 - // offset for 2 bytes can be 1 or 2 - switch (size) { - case 1: - val = in8 (CONFIG_DATA_PORT + (reg & 3)); - break; - case 2: - if ((reg & 3) != 3) - val = in16(CONFIG_DATA_PORT + (reg & 3)); - else { - val = EINVAL; - dprintf("ERROR: read_pci_config: can't read 2 bytes at reg %d (offset 3)!\n",reg); - } - break; - case 4: - if ((reg & 3) == 0) - val = in32(CONFIG_DATA_PORT); - else { - val = EINVAL; - dprintf("ERROR: read_pci_config: can't read 4 bytes at reg %d (offset != 0)!\n",reg); - } - break; - default: - dprintf("ERROR: mech #1: read_pci_config: called for %d bytes!!\n", size); - } - } else if (gConfigMechanism == 2) { - if (!(device & 0x10)) { - out8((uint8)(0xF0 | (function << 1)), 0xCF8); - out8(bus, 0xCFA); - - switch (size) { - case 1: - val = in8 (CONFIG_ADDR_2(device, reg)); - break; - case 2: - val = in16(CONFIG_ADDR_2(device, reg)); - break; - case 4: - val = in32(CONFIG_ADDR_2(device, reg)); - break; - default: - dprintf("ERROR: mech #2: read_pci_config: called for %d bytes!!\n", size); - } - out8(0, 0xCF8); - } else - val = EINVAL; - } else - dprintf("PCI: Config Mechanism %d isn't known!\n", gConfigMechanism); - - PCI_UNLOCK_CONFIG(cpu_status); - return val; -} - - -static void -write_pci_config(uchar bus, uchar device, uchar function, uchar reg, uchar size, uint32 value) -{ - int cpu_status; - - PCI_LOCK_CONFIG(cpu_status); - - if (gConfigMechanism == 1) { - /* write request details */ - out32(CONFIG_ADDR_1(bus, device, function, reg), CONFIG_REQ_PORT); - // Now read data back from the data port: - // offset for 1 byte can be 1, 2 or 3 - // offset for 2 bytes can be 1 or 2 - switch (size) { - case 1: - out8 (value, CONFIG_DATA_PORT + (reg & 3)); - break; - case 2: - if ((reg & 3) != 3) - out16(value, CONFIG_DATA_PORT + (reg & 3)); - else - dprintf("ERROR: write_pci_config: can't write 2 bytes at reg %d (offset 3)!\n",reg); - break; - case 4: - if ((reg & 3) == 0) - out32(value, CONFIG_DATA_PORT); - else - dprintf("ERROR: write_pci_config: can't write 4 bytes at reg %d (offset != 0)!\n",reg); - break; - default: - dprintf("ERROR: write_pci_config: called for %d bytes!!\n", size); - } - } else if (gConfigMechanism == 2) { - if (!(device & 0x10)) { - out8((uint8)(0xF0 | (function << 1)), 0xCF8); - out8(bus, 0xCFA); - - switch (size) { - case 1: - out8 (value, CONFIG_ADDR_2(device, reg)); - break; - case 2: - out16(value, CONFIG_ADDR_2(device, reg)); - break; - case 4: - out32(value, CONFIG_ADDR_2(device, reg)); - break; - default: - dprintf("ERROR: write_pci_config: called for %d bytes!!\n", size); - } - out8(0, 0xCF8); - } - } else - dprintf("PCI: Config Mechanism %d isn't known!\n", gConfigMechanism); - - PCI_UNLOCK_CONFIG(cpu_status); - - return; -} - - -/* pci_get_capability - * Try to get the offset and value of the specified capability - * from the devices capability list. - */ - -static bool -pci_get_capability(uint8 bus, uint8 dev, uint8 func, uint8 cap, uint8 *offs) -{ - uint16 status; - uint8 headerType; - uint8 ofs; - int maxcount; - - status = read_pci_config(bus, dev, func, PCI_status, 2); - if (!(status & PCI_status_capabilities)) - return false; - - headerType = read_pci_config(bus, dev, func, PCI_header_type, 1); - switch (headerType & 0x7f) { /* mask off multi function device indicator bit */ - case PCI_header_type_generic: - ofs = PCI_capabilities_ptr; - break; - case PCI_header_type_PCI_to_PCI_bridge: - dprintf("ERROR: pci_get_capability: PCItoPCI bridge header type has no capabilities pointer???\n"); - return false; - case PCI_header_type_cardbus: - ofs = PCI_capabilities_ptr_2; - break; - default: - dprintf("ERROR: pci_get_capability: unknown PCI header type\n"); - return false; - } - - // The 192 bytes vendor-defined configuration space can - // hold, as maximum, 48 times a 32-bit aligned capability. - // We use this as abort condition to avoid lock up by - // searching in a circular loop on bad hardware. - - maxcount = 48; - ofs = read_pci_config(bus, dev, func, ofs, 1); - while (maxcount-- > 0 && ofs != 0) { - - // mask off low two bits, demanded by PCI standard - ofs &= ~3; - - // PCI specification 2.2, section 6.8.1.1 and following - // describe capability ID and next capability position as - // two 8 bit values, the "capability ID" is at the 32 bit - // aligned position, after it the "next pointer" follows. - - // read the 8 bit capability id is at the 32-bit aligned ofs position - if (read_pci_config(bus, dev, func, ofs, 1) == cap) { - if (offs) - *offs = ofs; - return true; - } - - // at ofs + 1, we can read the next capability position - ofs = read_pci_config(bus, dev, func, ofs + 1, 1); - } - return false; -} - - -/* pci_set_power_state - * This attempts to set the device into one of the 4 power management - * modes, where PCI_pm_state_d0 is "Full Power" and _d3 is the lowest. - * The delay's at the end come from code I've seen but they really need - * to be checked against the spec, which can be found at - * PCI PM 1.1, section 5.6.1 table 18 - * - * There is a note on Linux to say that whilst we can jump straight to - * D0 we can't move to D3 unless we're already at D1, though the code they - * use to check this seems suspect. We may want to check against the spec. - * - * Returns - * EIO if the device doesn't support the power management state requested - * - */ - -static int -pci_set_power_state(uint8 bus, uint8 dev, uint8 func, int state) -{ - uint8 pm_reg; - uint8 cur_state; - uint16 cur_status; - - if (pci_get_capability(bus, dev, func, PCI_cap_id_pm, &pm_reg) == 0) - return EIO; - - if (state > PCI_pm_state_d3) - state = PCI_pm_state_d3; - - cur_status = read_pci_config(bus, dev, func, pm_reg + PCI_pm_status, 1); - cur_state = cur_status & PCI_pm_mask; - - if (cur_state == state) - return 0; - - if (state == PCI_pm_state_d1 || state == PCI_pm_state_d2) { - uint16 pmc = read_pci_config(bus, dev, func, pm_reg + PCI_pm_ctrl, 2); - if (state == PCI_pm_state_d1 && !(pmc & PCI_pm_d1supp)) - return EIO; - if (state == PCI_pm_state_d2 && !(pmc & PCI_pm_d2supp)) - return EIO; - } - - if (cur_state != PCI_pm_state_d3) { - cur_status &= ~PCI_pm_mask; - cur_status |= state; - } - - write_pci_config(bus, dev, func, pm_reg + PCI_pm_status, 2, cur_status); - - if (state == PCI_pm_state_d3 || cur_state == PCI_pm_state_d3) - snooze(10 * 1000); - else if (state == PCI_pm_state_d2 || cur_state == PCI_pm_state_d2) - snooze(200); - - return 0; -} - - -/** This used to be fixup_host_bridges, but some PCI-PCI bridges need - * to be adjusted as well so I'll make it more general. - * - * Partially borrowed from NetBSD. - */ - -static void -fixup_bridge(uint8 bus, uint8 dev, uint8 func) -{ - uint16 vendor; - uint16 device; - - vendor = read_pci_config(bus, dev, func, PCI_vendor_id, 2); - device = read_pci_config(bus, dev, func, PCI_device_id, 2); - - switch (vendor) { - case PCI_VENDOR_INTEL: - switch (device) { - case PCI_PRODUCT_INTEL_82443BX_AGP: - case PCI_PRODUCT_INTEL_82443BX_NOAGP: - { - // BIOS bug workaround: - // While the datasheet indicates that the only valid setting - // for "Idle/Pipeline DRAM Leadoff Timing (IPLDT)" is 01, - // some BIOS's do not set these correctly, so we check and - // correct if required. - - uint16 reg = read_pci_config(bus, dev, func, 0x76, 2); - - if ((reg & 0x0300) != 0x0100) { - dprintf("Intel 82443BX Host Bridge: Fixing IPDLT setting\n"); - reg &= ~0x0300; - reg |= 0x100; - write_pci_config(bus, dev, func, 0x76, 2, reg); - } - break; - } - } - break; - - default: - break; - } -} - - -/* Given a vendor/device pairing, do we need to scan through - * the entire set of funtions? normally the return will be false, - * implying we don't need to, but for some it will be true which - * means scan all functions. - * This function may seem overkill but it prevents scanning - * functions we don't need to and shoudl reduce the possibility of - * duplicates being detected. - */ - -static bool -pci_quirk_multifunction(uint16 vendor, uint16 device) -{ - switch (vendor) { - case PCI_VENDOR_INTEL: - switch (device) { - case PCI_PRODUCT_INTEL_82371AB_ISA: - case PCI_PRODUCT_INTEL_82371AB_IDE: - case PCI_PRODUCT_INTEL_82371AB_USB: - case PCI_PRODUCT_INTEL_82371AB_PMC: - return true; - } - } - - return false; -} - - -/* set_pci_mechanism() - * Try to determine which configuration mechanism the PCI Host Bridge - * wants to deal with. - * ToDo: we really should add code to detect and use a PCI BIOS - * if one exists, and this code then becomes the fallback. - * For now we'll just use this. - */ - -static bool -set_pci_mechanism(void) -{ - uint32 ckval = 0x80000000; - - // Start by looking for the older and more limited mechanism 2 - // as the test will probably work for mechanism 1 as well. - // - // This code copied/adapted from OpenBSD. - -#define PCI_MODE2_ENABLE 0x0cf8 -#define PCI_MODE2_FORWARD 0x0cfa - - out8(0, PCI_MODE2_ENABLE); - out8(0, PCI_MODE2_FORWARD); - - if (in8(PCI_MODE2_ENABLE) == 0 && - in8(PCI_MODE2_FORWARD) == 0) { - dprintf("PCI_Mechanism 2 test passed\n"); - gMaxBusDevices = 16; - gConfigMechanism = 2; - return true; - } - - // If we get here, the first test (for mechanism 2) failed, so there - // is a good chance this one will pass. Basically enable, then disable, - // and make sure we have the same values. - -#define PCI_MODE1_ADDRESS 0x0cf8 - - out32(ckval, PCI_MODE1_ADDRESS); - if (in32(PCI_MODE1_ADDRESS) == ckval) { - out32(0, PCI_MODE1_ADDRESS); - if (in32(PCI_MODE1_ADDRESS) == 0) { - dprintf("PCI_Mechanism 1 test passed\n"); - gMaxBusDevices = 32; - gConfigMechanism = 1; - return true; - } - } - - dprintf("PCI: Failed to find a valid PCI Configuration Mechanism!\n" - "PCI: disabled\n"); - gConfigMechanism = 0; - - return false; -} - - -/* check_pci() - * Basically PCI bus #0 "should" contain a PCI Host Bridge. - * This can be identified by the 8 bit pci class base of 0x06. - * - * XXX - this is pretty simplistic and needs improvement. In particular - * some Intel & Compaq bridges don't have the correct class base set. - * Need to review these. For the time being if this sanity check - * fails it won't be a hanging offense, but it will generate a - * message asking for the info to be sent to the kernel list so we - * can refine this code. :) Assuming anyone ever looks at the - * debug output! - * - * returns 0 if PCI seems to be OK - * -1 if PCI fails the test - */ - -static bool -check_pci(void) -{ - int dev = 0; - - // scan thru the first 16 devices on bus 0 looking for a PCI Host Bridge - for (dev = 0; dev < gMaxBusDevices; dev++) { - uint8 val = read_pci_config(0, dev, 0, PCI_class_base, 1); - if (val == 0x06) - return true; - } - - // Bit wordy, but it needs to be :( - dprintf("*** PCI Warning! ***\n" - "The PCI sanity check appears to have failed on your system.\n" - "This is probably due to the test being used, so please email\n" - "\topen-beos-kernel-devel@lists.sourceforge.net\n" - "Your assistance will help improve this test :)\n" - "***\n" - "PCI will attempt to continue normally.\n"); - - return false; -} - - -/* Intel specific - * - * See http://www.microsoft.com/hwdev/archive/BUSBIOS/pciirq.asp - * - * Intel boards have a PCI IRQ Routing table that contains details of - * how things get routed, information we need :( - */ - -struct linkmap { - uint8 pin; - uint16 possible_irq; -} _PACKED; - - -struct pir_slot { - uint8 bus; - uint8 devfunc; - struct linkmap linkmap[4]; - uint8 slot; - uint8 reserved; -} _PACKED; - - -#define PIR_HEADER "$PIR" - -struct pir_header { - char signature[4]; /* always '$PIR' */ - uint16 version; - uint16 tbl_sz; - uint8 router_bus; - uint8 router_devfunc; - uint16 exclusive_irq; - uint32 compat_vend; - uint32 miniport; - uint8 rsvd[11]; - uint8 cksum; -} _PACKED; - - -struct pir_table { - struct pir_header hdr; - struct pir_slot slot[1]; -} _PACKED; - - -#define PIR_DEVICE(devfunc) (((devfunc) >> 3) & 0x1f) -#define PIR_FUNCTION(devfunc) ((devfunc) & 0x07) - - -/* find_pir_table - * No real magic, just scan through the memory until we find it, - * or not! - * - * When we check the size of the table, we need to satisfy that - * size >= size of a pir_table with no pir_slots - * size <= size of a pir_table with 32 pir_slots - * If we find a table, and it's a suitable size we'll check that the - * checksum is OK. This is done by simply adding up all the bytes and - * checking that the final value == 0. If it is we return the pointer to the table. - * - * Returns NULL if we fail to find a suitable table. - */ - -static struct pir_table * -find_pir_table(void) -{ - addr mem_addr = gPCI_BIOS_Address; - int range = 0x10000; - - for (; range > 0; range -= 16, mem_addr += 16) { - if (memcmp((void*)mem_addr, PIR_HEADER, 4) == 0) { - uint16 size = ((struct pir_header*)mem_addr)->tbl_sz; - if ((size >= (sizeof(struct pir_header))) && - (size <= (sizeof(struct pir_header) + sizeof(struct pir_slot) * 32))) { - uint16 i; - uint8 cksum = 0; - - for (i = 0; i < size; i++) - cksum += ((uint8*)mem_addr)[i]; - - if (cksum == 0) - return (struct pir_table *)mem_addr; - } - } - } - - return NULL; -} - - -#if TRACE_PCI -/* print_pir_table - * Print out the table to debug output - */ - -static void -print_pir_table(struct pir_table *tbl) -{ - int i, j; - int entries = (tbl->hdr.tbl_sz - sizeof(struct pir_header)) / sizeof(struct pir_slot); - - for (i = 0; i < entries; i++) { - dprintf("PIR slot %d: bus %d, device %d\n", - tbl->slot[i].slot, tbl->slot[i].bus, - PIR_DEVICE(tbl->slot[i].devfunc)); - for (j = 0; j < 4; j++) - dprintf("\tINT%c: pin %d possible_irq's %04x\n", - 'A'+j, tbl->slot[i].linkmap[j].pin, - tbl->slot[i].linkmap[j].possible_irq); - } - - dprintf("*** end of table\n"); -} -#endif - - -/* Scanning for Devices - * ==================== - * - * http://www.tldp.org/LDP/tlk/dd/pci.html - * - * Although it refers to Linux it gives a good overview of the basic - * methodology they use for scanning PCI. We've adopted a similar - * approach here, using the "depthwise" algorithm. - * - * We start by scanning a bus, which treats every device it finds the - * same and passes them onto pci_probe_device(). - * pci_probe_device() sends pci_bridges to pci_bridge() to be setup - * and deals with type 0 (generic) devices itself. - * - * ToDo: currently we don't really cope with type 2 (Cardbus) devices - * but will need to eventually. - */ - - -/** The values passed in specify the "device" on the bus being searched - * that has been identified as a PCI-PCI bridge. We now setup that bridge - * and scan the bus it defines. - * The bus is initially taken off-line, scanned and then put back on-line - * - * We initally set the subordinate_bus to 0xff and then adjust it to the max - * once we've scanned the bus on the other side of the bridge. See the URL - * above for information on why this is done. - */ - - /* All PCI buses located behind a PCI-PCI bridge must reside between the seondary bus number and the subordinate bus number (inclusive). */ - -static void -pci_bridge(uint8 bus, uint8 dev, uint8 func) -{ - uint16 command; - uint8 bridge; - pci_device *pciDevice; - pci_bus *pciBus; - pci_info *pciInfo; - - TRACE(("pci_bridge()\n")); - - command = read_pci_config(bus, dev, func, PCI_command, 2); - command &= ~0x03; - write_pci_config(bus, dev, func, PCI_command, 2, command); - - // gMaxBusDetected is incremented before we use bridge below and - // before we recurse to preserve the correct relationships with numbering. - bridge = ++gMaxBusDetected; - - write_pci_config(bus, dev, func, PCI_primary_bus, 1, bus); - write_pci_config(bus, dev, func, PCI_secondary_bus, 1, bridge); - write_pci_config(bus, dev, func, PCI_subordinate_bus, 1, 0xff); - - dprintf("PCI-PCI bridge at %d:%d:%d configured as bus %d\n", bus, dev, func, bridge); - pci_scan_bus(bridge); - - write_pci_config(bus, dev, func, PCI_subordinate_bus, 1, gMaxBusDetected); - - pciInfo = (pci_info *)malloc(sizeof(pci_info)); - if (!pciInfo) - goto pci_bridge_skip_infolist; - - pciDevice = (pci_device *)malloc(sizeof(pci_device)); - if (!pciDevice) { - free(pciInfo); - goto pci_bridge_skip_infolist; - } - pciBus = (pci_bus *)malloc(sizeof(pci_bus)); - if (!pciBus) { - free(pciInfo); - free(pciDevice); - goto pci_bridge_skip_infolist; - } - - pciDevice->info = pciInfo; - pciDevice->type = PCI_BRIDGE; - pciDevice->next = NULL; - - pciBus->info = pciInfo; - pciBus->next = NULL; - - pciInfo->bus = bus; - pciInfo->device = dev; - pciInfo->function = func; - - fill_basic_pci_structure(pciInfo); - - pciInfo->u.h1.rom_base_pci = read_pci_config(bus, dev, func, PCI_bridge_rom_base, 4); - pciInfo->u.h1.primary_bus = read_pci_config(bus, dev, func, PCI_primary_bus, 1); - pciInfo->u.h1.secondary_bus = read_pci_config(bus, dev, func, PCI_secondary_bus, 1); - pciInfo->u.h1.secondary_latency = read_pci_config(bus, dev, func, PCI_secondary_latency, 1); - pciInfo->u.h1.secondary_status = read_pci_config(bus, dev, func, PCI_secondary_status, 2); - pciInfo->u.h1.subordinate_bus = read_pci_config(bus, dev, func, PCI_subordinate_bus, 1); - pciInfo->u.h1.memory_base = read_pci_config(bus, dev, func, PCI_memory_base, 2); - pciInfo->u.h1.memory_limit = read_pci_config(bus, dev, func, PCI_memory_limit, 2); - pciInfo->u.h1.prefetchable_memory_base = read_pci_config(bus, dev, func, PCI_prefetchable_memory_base, 2); - pciInfo->u.h1.prefetchable_memory_limit = read_pci_config(bus, dev, func, PCI_prefetchable_memory_limit, 2); - pciInfo->u.h1.bridge_control = read_pci_config(bus, dev, func, PCI_bridge_control, 1); - pciInfo->u.h1.subsystem_vendor_id = read_pci_config(bus, dev, func, PCI_sub_vendor_id_1, 2); - pciInfo->u.h1.subsystem_id = read_pci_config(bus, dev, func, PCI_sub_device_id_1, 2); - pciInfo->u.h1.interrupt_line = read_pci_config(bus, dev, func, PCI_interrupt_line, 1); - pciInfo->u.h1.interrupt_pin = read_pci_config(bus, dev, func, PCI_interrupt_pin, 1) & PCI_pin_mask; - - { - pci_device *pd = gPCI_Devices; - while (pd && pd->next) - pd = pd->next; - - if (pd) - pd->next = pciDevice; - else - gPCI_Devices = pciDevice; - } - { - pci_bus *pb = gPCI_Busses; - while (pb && pb->next) - pb = pb->next; - - if (pb) - pb->next = pciBus; - else - gPCI_Busses = pciBus; - } - - show_pci_details(pciInfo); - -pci_bridge_skip_infolist: - command |= 0x03; - write_pci_config(bus, dev, func, PCI_command, 2, command); - return; -} - - -/** This is a very, very brief 2 liner for a device... */ - -static void -debug_show_device(pci_info *pciInfo) -{ - uint8 bus = pciInfo->bus; - uint8 dev = pciInfo->device; - uint8 func = pciInfo->function; - - uint16 status = read_pci_config(bus, dev, func, PCI_status, 2); - - dprintf("device @ %d:%d:%d > %s [%04x:%04x]\n", bus, dev, func, - decode_class(pciInfo->class_base, pciInfo->class_sub), - pciInfo->vendor_id, pciInfo->device_id); - - if ((status & PCI_status_capabilities)) { - dprintf("Capabilities: "); - if (pci_get_capability(bus, dev, func, PCI_cap_id_agp, NULL)) - dprintf("AGP "); - if (pci_get_capability(bus, dev, func, PCI_cap_id_pm, NULL)) - dprintf("Pwr Mgmt "); - if (pci_get_capability(bus, dev, func, PCI_cap_id_vpd, NULL)) - dprintf("VPD "); - if (pci_get_capability(bus, dev, func, PCI_cap_id_slotid, NULL)) - dprintf("slotID "); - if (pci_get_capability(bus, dev, func, PCI_cap_id_msi, NULL)) - dprintf("MSI "); - if (pci_get_capability(bus, dev, func, PCI_cap_id_hotplug, NULL)) - dprintf("hotplug "); - dprintf("\n"); - } else - dprintf("\t(No capabilities exist for this device)\n"); -} - - -static void -pci_device_probe(uint8 bus, uint8 dev, uint8 func) -{ - uint8 base_class; - uint8 sub_class; - uint8 type; - pci_info *pciInfo; - pci_device *pciDevice; - - TRACE(("pci_device_probe()\n")); - - if (func > 0) { - uint16 vend = read_pci_config(bus, dev, func, PCI_vendor_id, 2); - if (vend == 0xffff) - return; - } - - type = read_pci_config(bus, dev, func, PCI_header_type, 1); - type &= PCI_header_type_mask; - base_class = read_pci_config(bus, dev, func, PCI_class_base, 1); - sub_class = read_pci_config(bus, dev, func, PCI_class_sub, 1); - - if (base_class == PCI_bridge) { - fixup_bridge(bus, dev, func); - if (sub_class == PCI_pci) { - pci_bridge(bus, dev, func); - return; - } - } - - // If we get here then it's not a bridge, so we add it... - pciInfo = (pci_info *)malloc(sizeof(pci_info)); - if (!pciInfo) - return; - - pciDevice = (pci_device *)malloc(sizeof(pci_device)); - if (!pciDevice) { - free(pciInfo); - return; - } - - pciDevice->info = pciInfo; - pciDevice->type = PCI_DEVICE; - pciDevice->next = NULL; - - pciInfo->bus = bus; - pciInfo->device = dev; - pciInfo->function = func; - - fill_basic_pci_structure(pciInfo); - - if (pciInfo->class_base == PCI_bridge && pciInfo->class_sub == PCI_host) - pciDevice->type = PCI_HOST_BUS; - - pciInfo->u.h0.cardbus_cis = read_pci_config(bus, dev, func, PCI_cardbus_cis, 4); - pciInfo->u.h0.subsystem_id = read_pci_config(bus, dev, func, PCI_subsystem_id, 2); - pciInfo->u.h0.subsystem_vendor_id = read_pci_config(bus, dev, func, PCI_subsystem_vendor_id, 2); - pciInfo->u.h0.rom_base_pci = read_pci_config(bus, dev, func, PCI_rom_base, 4); - pciInfo->u.h0.interrupt_line = read_pci_config(bus, dev, func, PCI_interrupt_line, 1); - pciInfo->u.h0.interrupt_pin = read_pci_config(bus, dev, func, PCI_interrupt_pin, 1) & PCI_pin_mask; - - // now add to list (at end) - { - pci_device *pd = gPCI_Devices; - while (pd && pd->next) - pd = pd->next; - - if (pd) - pd->next = pciDevice; - else - gPCI_Devices = pciDevice; - } - pci_set_power_state(bus, dev, func, PCI_pm_state_d0); - - debug_show_device(pciInfo); -} - - -/** Scan a bus for PCI devices. For each device that's a possible - * we get the vendor_id. If it's 0xffff then it's not a valid - * device so we move on. - * Valid devices then have their header_type checked to detrmine how - * many functions we need to check. However, some devices that support - * multiple functions have a header_type of 0 (generic) so we also check - * for these using pci_quirk_multifunction(). - * If it's a multifunction device we scan all 8 possible functions, - * otherwise we just probe the first one. - */ - -static void -pci_scan_bus(uint8 bus) -{ - uint8 dev = 0; - uint8 func = 0; - - TRACE(("pci_scan_bus()\n")); - - for (dev = 0; dev < 32; dev++) { - uint16 vendorID = read_pci_config(bus, dev, 0, PCI_vendor_id, 2); - if (vendorID != 0xffff) { - uint16 device = read_pci_config(bus, dev, func, PCI_device_id, 2); - uint8 type = read_pci_config(bus, dev, func, PCI_header_type, 1); - uint8 nfunc = 8; - - type &= PCI_header_type_mask; - - if ((type & PCI_multifunction) == 0 - && !pci_quirk_multifunction(vendorID, device)) - nfunc = 1; - - for (func = 0; func < nfunc; func++) - pci_device_probe(bus, dev, func); - } - } -} - - -#if 0 -static void -scan_pci(void) -{ - int bus, dev, func; - - TRACE(("scan_pci()\n")); - - // We can have up to 255 busses - for (bus = 0; bus < 255; bus++) { - - // Each bus can have up to 'gMaxBusDevices' devices on it - for (dev = 0; dev <= gMaxBusDevices; dev++) { - uint16 sv_vendor_id = 0, sv_device_id = 0; - - // Each device can have up to 8 functions - for (func = 0; func < 8; func++) { - pci_info *pciInfo = NULL; - uint16 vendor_id = read_pci_config(bus, dev, func, 0, 2); - uint16 device_id; - uint8 offset; - - // If we get 0xffff then there is no device here. As there can't - // be any gaps in function allocation this tells us that we - // can move onto the next device/bus - if (vendor_id == 0xffff) - break; - - device_id = read_pci_config(bus, dev, func, PCI_device_id, 2); - - // Is this a new device? As we're scanning the functions here, many devices - // will supply identical information for all 8 accesses! Try to catch this and - // simply move past duplicates. We need to continue scanning in case we miss - // a different device at the end. - // - // XXX - is this correct???? - // - if (vendor_id == sv_vendor_id && sv_device_id == device_id) - // it's a duplicate - continue; - - sv_vendor_id = vendor_id; - sv_device_id = device_id; - - // At present we will add a device to our list if we get here, - // but we may want to review if we need to add 8 version of the - // same device if only the functions differ? - if ((pciInfo = (pci_info *)malloc(sizeof(pci_info))) == NULL) { - dprintf("Failed to get memory for a pic_info structure in scan_pci\n"); - return; - } - - if (pci_get_capability(bus, dev, func, PCI_cap_id_agp, &offset)) - dprintf("Device @ %d:%d:%d has AGP capability\n", bus, dev, func); - - pci_set_power_state(bus, dev, func, PCI_pm_state_d0); - - // basic header - pciInfo->bus = bus; - pciInfo->device = dev; - pciInfo->function = func; - pciInfo->vendor_id = vendor_id; - pciInfo->device_id = device_id; - - pciInfo->revision = read_pci_config(bus, dev, func, PCI_revision, 1); - pciInfo->class_api = read_pci_config(bus, dev, func, PCI_class_api, 1); - pciInfo->class_sub = read_pci_config(bus, dev, func, PCI_class_sub, 1); - pciInfo->class_base = read_pci_config(bus, dev, func, PCI_class_base, 1); - - pciInfo->header_type = read_pci_config(bus, dev, func, PCI_header_type, 1); - pciInfo->header_type &= PCI_header_type_mask; - } - } - } -} -#endif - - -static void -fill_basic_pci_structure(pci_info *pciInfo) -{ - uint8 bus = pciInfo->bus, dev = pciInfo->device, func = pciInfo->function; - uint8 int_line = 0, int_pin = 0; - - pciInfo->vendor_id = read_pci_config(bus, dev, func, PCI_vendor_id, 2); - pciInfo->device_id = read_pci_config(bus, dev, func, PCI_device_id, 2); - - pciInfo->revision = read_pci_config(bus, dev, func, PCI_revision, 1); - pciInfo->class_api = read_pci_config(bus, dev, func, PCI_class_api, 1); - pciInfo->class_sub = read_pci_config(bus, dev, func, PCI_class_sub, 1); - pciInfo->class_base = read_pci_config(bus, dev, func, PCI_class_base, 1); - - pciInfo->header_type = read_pci_config(bus, dev, func, PCI_header_type, 1); - pciInfo->header_type &= PCI_header_type_mask; - - pciInfo->latency = read_pci_config(bus, dev, func, PCI_latency, 1); - pciInfo->bist = read_pci_config(bus, dev, func, PCI_bist, 1); - pciInfo->line_size = read_pci_config(bus, dev, func, PCI_line_size, 1); - - int_line = read_pci_config(bus, dev, func, PCI_interrupt_line, 1); - int_pin = read_pci_config(bus, dev, func, PCI_interrupt_pin, 1); - int_pin &= PCI_pin_mask; -} - - -/* ToDo: check the return values from this function. */ - -static long -get_nth_pci_info(long index, pci_info *copyto) -{ - // We copy the index and then decrement it. - // We also set the start found_pci_device pointer - // to the first device found and inserted. - // XXX - see discussion below. - - long count = index; - pci_device *pd = gPCI_Devices; - - TRACE(("pci_nth_pci_info()\n")); - - // iterate through the list until we have count == 0 - // Note: we go in "reverse" as the devices are inserted into the list - // at the start, so going "forward" would give us the last device first. - // - // XXX - do we want to reverse this decision and go "forwards"? - // this should reduce the number of tries we make to find - // a "device" as the system devices are the first ones found - // and therefore the last ones to be returned. - // - // XXX - if we do decide to reverse the order we need to be very - // careful about which function # gets found first and returned. - while (count-- > 0 && pd) - pd = pd->next; - - if (count > 0 || !pd || !pd->info) - // we are bailing out here because either: - // a) we don't have enough devices to fulfill the request - // e.g. user asked for dev #31 but we only have 30 - // b) The found_device_structure has a NULL pointer for - // info, which would cause a segfault when we try to memcpy! - return B_DEV_ID_ERROR; - - memcpy(copyto, pd->info, sizeof(pd->info)); - return 0; -} - - - -/* - * I/O routines - * - */ - -static uint8 -pci_read_io_8(int mapped_io_addr) -{ - return in8(mapped_io_addr); -} - - -static void -pci_write_io_8(int mapped_io_addr, uint8 value) -{ - out8(value, mapped_io_addr); -} - - -static uint16 -pci_read_io_16(int mapped_io_addr) -{ - return in16(mapped_io_addr); -} - - -static void -pci_write_io_16(int mapped_io_addr, uint16 value) -{ - out16(value, mapped_io_addr); -} - - -static uint32 -pci_read_io_32(int mapped_io_addr ) -{ - return in32(mapped_io_addr); -} - - -static void -pci_write_io_32(int mapped_io_addr, uint32 value) -{ - out32(value, mapped_io_addr); -} - - - -/* pci_module_init - * - * This is where we start all the PCI work, or not as the case may be. - * We start by trying to detect and set the correct configuration mechanism - * to use. We don't handle PCI BIOS's as that method seems to be falling out - * of fashion and is Intel specific. - * - * Next we try to check if we have working PCI on this machine. check_pci() - * isn't the smartest routine as it essentially just looks for a Host-PCI - * bridge, but it will show us if we can continue. - * Note: Until this has been tested with a wider audience we don't consider - * success/failure here but spew a large debug message and try to continue. - * XXX - once we're happy with check_pci() make failing a criminal offense! - * - * Next we check to see if we can find a PIR table. - * Note: This is Intel specific and currently included here as a test. - * - * Finally we scan for devices starting at bus 0. - */ - -static void -pci_module_init(void) -{ - struct pir_table *pirTable = NULL; - - TRACE(("pci_module_init()\n")); - - if (!set_pci_mechanism()) - return; - - check_pci(); - - gPCI_Region = map_physical_memory("pci_bios", (void *)0xf0000, - 0x10000, B_ANY_KERNEL_ADDRESS, B_KERNEL_READ_AREA, - (void **)&gPCI_BIOS_Address); - - pirTable = find_pir_table(); - if (pirTable) { - dprintf("PCI IRQ Routing table found\n"); -#if TRACE_PCI - print_pir_table(pirTable); -#endif - } - - pci_scan_bus(0); -} - - -/** Finish the module by releasing the memory we grabbed for - * the pci_bios :) - */ - -static void -pci_module_uninit(void) -{ - delete_area(gPCI_Region); -} - - -static int32 -std_ops(int32 op, ...) -{ - switch (op) { - case B_MODULE_INIT: - dprintf("PCI: init\n"); - pci_module_init(); - return B_OK; - - case B_MODULE_UNINIT: - dprintf("PCI: uninit\n"); - pci_module_uninit(); - return B_OK; - } - - return EINVAL; -} - - -struct pci_module_info pci_module = { - { - { - B_PCI_MODULE_NAME, - B_KEEP_LOADED, - std_ops - }, - NULL // &pci_rescan - }, - - &pci_read_io_8, - &pci_write_io_8, - &pci_read_io_16, - &pci_write_io_16, - &pci_read_io_32, - &pci_write_io_32, - &get_nth_pci_info, - &read_pci_config, - &write_pci_config, - NULL, // &ram_address -}; - - -module_info *modules[] = { - (module_info *)&pci_module, - NULL -}; - diff --git a/src/kernel/core/addons/bus_managers/pci/pci_bus.c b/src/kernel/core/addons/bus_managers/pci/pci_bus.c deleted file mode 100644 index aaa55e4eb6..0000000000 --- a/src/kernel/core/addons/bus_managers/pci/pci_bus.c +++ /dev/null @@ -1,347 +0,0 @@ -/* -** Copyright 2001, Travis Geiselbrecht. All rights reserved. -** Distributed under the terms of the NewOS License. -*/ - -#include -#include -#include -#include -#include - -#include - -#include - -#include "pci_p.h" // private includes - -/* While this will now print details of all the PCI devices it finds, for a full - * description of the devices you'll need to add the information. As the header is - * 275k I haven't just included it while we're still working on a floppy image, - * but rather it's inclusion is optional. - * - * If you want to include the header for more information, you'll need to - * 1) get a copy of pcihdr.h from http://www.yourvote.com/pci/ and modify it - * 2) copy it into the pci directory (ie here) - * 3) change the define of USE_PCIHDR from 0 to 1 - * 4) rebuild - */ -#define USE_PCIHDR 0 -#if USE_PCIHDR -# include "pcihdr.h" -#endif - -int pci_scan_all(); - -struct pci_fs { - mount_id id; - mutex lock; - void *covered_vnode; - void *redir_vnode; - int root_vnode; /* just a placeholder to return a pointer to */ -}; - - -static unsigned int -pci_read_data(uint8 bus, uint8 unit, uint8 function, int reg, int bytes) -{ - struct pci_config_address addr; - addr.enable = 1; - addr.reserved = 0; - addr.bus = bus; - addr.unit = unit; - addr.function = function; - addr.reg = reg & 0xfc; - - out32(*(unsigned int *)&addr, CONFIG_ADDRESS); - switch(bytes) { - case 1: - return in8(CONFIG_DATA + (reg & 3)); - case 2: - return in16(CONFIG_DATA + (reg & 3)); - case 4: - return in32(CONFIG_DATA + (reg & 3)); - default: - return 0; - } -} - - -static void -pci_write_data(uint8 bus, uint8 unit, uint8 function, int reg, uint32 data, int bytes) -{ - struct pci_config_address addr; - addr.enable = 1; - addr.reserved = 0; - addr.bus = bus; - addr.unit = unit; - addr.function = function; - addr.reg = reg & 0xfc; - - out32(*(unsigned int *)&addr, CONFIG_ADDRESS); - switch(bytes) { - case 1: - out8(data, CONFIG_DATA + (reg & 3)); - break; - case 2: - out16(data, CONFIG_DATA + (reg & 3)); - break; - case 4: - out32(data, CONFIG_DATA + (reg & 3)); - break; - } - return; -} - - -static int -pci_read_config(uint8 bus, uint8 unit, uint8 func, struct pci_cfg *cfg) -{ - union { - struct pci_cfg cfg; - uint32 word[4]; - } u; - int i; - - for (i = 0; i<4; i++) { - u.word[i] = pci_read_data(bus, unit, func, 4*i, 4); - } - if (u.cfg.vendor_id == 0xffff) - return -1; - - // move over to the passed in config structure - memcpy(cfg, &u.cfg, sizeof(struct pci_cfg)); - cfg->bus = bus; - cfg->unit = unit; - cfg->func = func; - - switch (cfg->header_type & 0x7f) { - case 0: { // normal device - uint32 v; - for(i=0; i<6; i++) { - v = pci_read_data(bus, unit, func, i*4 + 0x10, 4); - if(v) { - int v2; - pci_write_data(bus, unit, func, i*4 + 0x10, 0xffffffff, 4); - v2 = pci_read_data(bus, unit, func, i*4 + 0x10, 4) & 0xfffffff0; - pci_write_data(bus, unit, func, i*4 + 0x10, v, 4); - v2 = 1 + ~v2; - if(v & 1) { - cfg->base[i] = v & 0xfff0; - cfg->size[i] = v2 & 0xffff; - } else { - cfg->base[i] = v & 0xfffffff0; - cfg->size[i] = v2; - } - } else { - cfg->base[i] = 0; - cfg->size[i] = 0; - } - } - v = pci_read_data(bus, unit, func, 0x3c, 1); - cfg->irq = (v == 0xff ? 0 : v); - break; - } - case 1: // PCI <-> PCI bridge - break; - default: - break; - } - return 0; -} - - -static const char * -pci_class_to_string(uint8 base_class) -{ - switch (base_class) { - case 0x00: return "legacy"; - case 0x01: return "mass storage"; - case 0x02: return "network"; - case 0x03: return "video"; - case 0x04: return "multimedia"; - case 0x05: return "memory"; - case 0x06: return "bridge"; - case 0x07: return "comms"; - case 0x08: return "system"; - case 0x09: return "input"; - case 0x0a: return "docking station"; - case 0x0b: return "processor"; - case 0x0c: return "serial bus controller"; - case 0x0d: return "wireless"; - case 0x0e: return "intelligent i/o ??"; - case 0x0f: return "satellite"; - case 0x10: return "encryption"; - case 0x11: return "signal processing"; - default: return "unknown"; - } -} - - -static const char * -pci_subclass_to_string(uint8 base_class, uint8 sub_class) -{ - switch(base_class) { - case 0: // legacy - return "unknown"; - case 1: // mass storage - switch(sub_class) { - case 0: return "scsi"; - case 1: return "ide"; - case 2: return "floppy"; - case 3: return "ipi"; - default: return "unknown"; - } - case 2: // network - switch(sub_class) { - case 0: return "ethernet"; - case 1: return "token_ring"; - case 2: return "fddi"; - default: return "unknown"; - } - case 3: // video - switch(sub_class) { - case 0: return "vga"; - case 1: return "xga"; - default: return "unknown"; - } - case 4: // multimedia - return "unknown"; - case 5: // memory - switch(sub_class) { - case 1: return "ram"; - default: return "unknown"; - } - case 6: // bridge - switch(sub_class) { - case 0: return "host"; - case 1: return "isa"; - case 2: return "eisa"; - case 3: return "mca"; - case 4: return "pcipci"; - case 5: return "pcmcia"; - case 0x80: return "other"; - default: return "unknown"; - } - default: return "unknown"; - } -} - - -void -dump_pci_config(struct pci_cfg *cfg) -{ - int i; - - dprintf("dump_pci_config: dumping cfg structure at %p\n", cfg); - - dprintf("\tbus: %d, unit: %d, function: %d\n", cfg->bus, cfg->unit, cfg->func); - - dprintf("\tvendor id: %d\n", cfg->vendor_id); - dprintf("\tdevice id: %d\n", cfg->device_id); - dprintf("\tcommand: %d\n", cfg->command); - dprintf("\tstatus: %d\n", cfg->status); - - dprintf("\trevision id: %d\n", cfg->revision_id); - dprintf("\tinterface: %d\n", cfg->interface); - dprintf("\tsub class: %d '%s'\n", cfg->sub_class, pci_subclass_to_string(cfg->base_class, cfg->sub_class)); - - dprintf("\tcache line size: %d\n", cfg->cache_line_size); - dprintf("\tlatency timer: %d\n", cfg->latency_timer); - dprintf("\theader type: %d\n", cfg->header_type); - dprintf("\tbist: %d\n", cfg->bist); - - dprintf("\tirq: %d\n", cfg->irq); - - for (i = 0; i < 6; i++) { - dprintf("\tbase[%d] = 0x%lx\n", i, cfg->base[i]); - dprintf("\tsize[%d] = 0x%lx\n", i, cfg->size[i]); - } -} - - -static void -dump_short_pci_config(struct pci_cfg *cfg) -{ -#if !USE_PCIHDR - dprintf("PCI: vendor id %d, device id %d ", cfg->vendor_id, cfg->device_id); - dprintf(", base class: %d '%s'\n", cfg->base_class, pci_class_to_string(cfg->base_class)); -#else - int i,j; - for (i = 0; i < PCI_VENTABLE_LEN; i++) { - if (PciVenTable[i].VenId == cfg->vendor_id) { - dprintf("PCI: %s: ", PciVenTable[i].VenFull); - for (j=0; j < PCI_DEVTABLE_LEN; j++) { - if (PciDevTable[j].VenId == cfg->vendor_id && - PciDevTable[j].DevId == cfg->device_id) - dprintf("%s %s", PciDevTable[j].Chip, PciDevTable[j].ChipDesc); - } - dprintf("\n"); - } - } -#endif -} - - -int -pci_probe(uint8 bus, uint8 unit, uint8 function, struct pci_cfg *cfg) -{ - if (function > 0) { - struct pci_cfg cfg1; - - // read info about the first unit - if (pci_probe(bus, unit, 0, &cfg1) < 0) - return -1; - - if (!(cfg1.header_type & 0x80)) { - // no multiple functions for this dev - return -1; - } - } - - if (pci_read_data(bus, unit, function, 0, 2) == 0xffff) - return -1; - - if (pci_read_config(bus, unit, function, cfg) < 0) - return -1; - - dump_short_pci_config(cfg); - - return 0; -} - -#if 0 - -int -pci_scan_all() -{ - int bus; - int unit; - int function; - - dprintf("pci_scan_all: entry\n"); - - for (bus = 0; bus < 255; bus++) { - for (unit = 0; unit < 32; unit++) { - for (function = 0; function < 8; function++) { - struct pci_cfg cfg; - - if (pci_read_data(bus, unit, function, 0, 2) == 0xffff) - break; - - if (pci_read_config(bus, unit, function, &cfg) < 0) - break; - - dump_short_pci_config(&cfg); - - if (!(cfg.header_type & 0x80)) { - // no multiple functions - break; - } - } - } - } - return 0; -} -#endif - diff --git a/src/kernel/core/main.c b/src/kernel/core/main.c index dbeecfc446..a56f004383 100644 --- a/src/kernel/core/main.c +++ b/src/kernel/core/main.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include